file manipulation in c++ - c++

I convert this code in python to c++:
content = file(filename, "rb").read()
this is the code in c++:
ifstream file;
file.open(filename, fstream::binary);
file.seekg (0, ios::end);
long fileLength = file.tellg();
file.seekg(0, ios_base::beg);
char *content = new char[fileLength];
file.read(content, fileLength);
when I run the python code I get a long string in the content (500 characters~) while the c++ code return only 4 characters.
any suggestion?
thanks

The simplest way to read an entire file is:
std::string content(
std::istreambuf_iterator<char>(std::ifstream(filename, std::fstream::binary).rdbuf()),
std::istreambuf_iterator<char>());

Related

Change the endianness when reading from a file

I'm trying to get better understanding of endianness when someone read a file.
The machine i'm using is little endian.
The code down below is supposed to read any file type.
But what if the file we are reading is in UTF-16BE encoding, should we after reading the whole file change the endianness?
I'm asking this becouse i'm planing on editing the content of the file and output it in console.
In case we should change the endianness, how can that be done?
Right now i'm reading the files like this:
std::ifstream file("/RANDOME/PATH/file.html", std::ios::in | std::ios::binary);
std::string result;
file.seekg(0, std::ios::end);
result.reserve(t.tellg());
file.seekg(0, std::ios::beg);
result.assign((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
file.close();
I have no idea how to change the endianness from Big to little when reading a file. Can someone kindly show me step by step how that is done correctly?
i'm only trying to learn. I know the file is using UTF-16BE encoding that is not a guess.
Here is some code that does what you want. Note that this code reads the input file a line at a time rather than reading it all in one fell swoop.
#include <string>
#include <fstream>
void swap_bytes (char16_t *s)
{
while (*s)
{
unsigned char *uc = (unsigned char *) s;
unsigned char swap = *uc;
*uc = uc [1];
uc [1] = swap;
++s;
}
}
int main ()
{
std::basic_ifstream <char16_t> file ("/RANDOME/PATH/file.html", std::ios::in);
if (!file)
return 1;
std::basic_string <char16_t> line;
while (std::getline (file, line))
{
swap_bytes (line.data ());
// ...
}
file.close();
}
If anything is unclear please say so in the comments.
Live demo

saving text file in binary

I have a project witch I have to back up my text files in binary mode with the destination that is getting from the user.
I was thinking to open my text files in binary and close them in the address that I have got from the user. but I don't know how to do that.
is there a way to close the files in a new address(saving them where ever I want) and not set an address directly because it's suppose to set by the user
Here is sample code to save the file:
#include <fstream>
int main () {
std::ofstream ofs;
ofs.open ("test.txt", std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
ofs << " data goes here";
ofs.close();
return 0;
}
The following is sample code to copy files:
ifstream source("from.txt", ios::binary);
ofstream dest("to.txt", ios::binary);
source.seekg(0, ios::end);
ifstream::pos_type size = source.tellg(); // file size
source.seekg(0);
char* buffer = new char[size]; // allocate memory for buffer
// copy file
source.read(buffer, size);
dest.write(buffer, size);
// clean up
delete[] buffer;
source.close();
dest.close();

C++ reading and writing a file results in garbage

I'm simply trying to read a small 1KB binary file into a buffer and then write the buffer back to the disk. It seems that for some files the outputfile is completely different from the Inputfile, what am I doing wrong?
Thank you very much.
std::ifstream myfile;
myfile.open (testinput.rar);
myfile.seekg (0, myfile.end);
filesize = myfile.tellg();
myfile.seekg (0, myfile.beg);
char *mybuffer= new char[filesize];
myfile.read(mybuffer,filesize);
myfile.close();
ofstream myfile3;
myfile3.open ("testoutput.rar");
for(unsigned int i=0; i<filesize; i++)
myfile3 << mybuffer[i];
myfile3.close();
You have to open the file as binary.
myfile.open ("testinput.rar", std::ios::binary);
myfile3 should be opened in binary mode:
myfile3.open("testoutput.rar", ios::out | ios::binary);
Additionally, you may want to consider using write() to modify files:
myfile3.write(mybuffer[i], sizeOfBuffer);

How to read the binary file in C++

I want to write a program that opens the binary file and encrypts it using DES.
But how can I read the binary file?
"how can I read the binary file?"
If you want to read the binary file and then process its data (encrypt it, compress, etc.), then it seems reasonable to load it into the memory in a form that will be easy to work with. I recommend you to use std::vector<BYTE> where BYTE is an unsigned char:
#include <fstream>
#include <vector>
typedef unsigned char BYTE;
std::vector<BYTE> readFile(const char* filename)
{
// open the file:
std::streampos fileSize;
std::ifstream file(filename, std::ios::binary);
// get its size:
file.seekg(0, std::ios::end);
fileSize = file.tellg();
file.seekg(0, std::ios::beg);
// read the data:
std::vector<BYTE> fileData(fileSize);
file.read((char*) &fileData[0], fileSize);
return fileData;
}
with this function you can easily load your file into the vector like this:
std::vector<BYTE> fileData = readfile("myfile.bin");
Hope this helps :)

Using C++ filestreams (fstream), how can you determine the size of a file?

I'm sure I've just missed this in the manual, but how do you determine the size of a file (in bytes) using C++'s istream class from the fstream header?
You can open the file using the ios::ate flag (and ios::binary flag), so the tellg() function will directly give you directly the file size:
ifstream file( "example.txt", ios::binary | ios::ate);
return file.tellg();
You can seek until the end, then compute the difference:
std::streampos fileSize( const char* filePath ){
std::streampos fsize = 0;
std::ifstream file( filePath, std::ios::binary );
fsize = file.tellg();
file.seekg( 0, std::ios::end );
fsize = file.tellg() - fsize;
file.close();
return fsize;
}
Don't use tellg to determine the exact size of the file. The length determined by tellg will be larger than the number of characters can be read from the file.
From stackoverflow question tellg() function give wrong size of file? tellg does not report the size of the file, nor the offset from the beginning in bytes. It reports a token value which can later be used to seek to the same place, and nothing more. (It's not even guaranteed that you can convert the type to an integral type.). For Windows (and most non-Unix systems), in text mode, there is no direct and immediate mapping between what tellg returns and the number of bytes you must read to get to that position.
If it is important to know exactly how many bytes you can read, the only way of reliably doing so is by reading. You should be able to do this with something like:
#include <fstream>
#include <limits>
ifstream file;
file.open(name,std::ios::in|std::ios::binary);
file.ignore( std::numeric_limits<std::streamsize>::max() );
std::streamsize length = file.gcount();
file.clear(); // Since ignore will have set eof.
file.seekg( 0, std::ios_base::beg );
Like this:
long begin, end;
ifstream myfile ("example.txt");
begin = myfile.tellg();
myfile.seekg (0, ios::end);
end = myfile.tellg();
myfile.close();
cout << "size: " << (end-begin) << " bytes." << endl;
Since C++17, we have std::filesystem::file_size. This doesn't strictly speaking use istream or fstream but is by far the most concise and correct way to read a file's size in standard C++.
#include <filesystem>
...
auto size = std::filesystem::file_size("example.txt");
I'm a novice, but this is my self taught way of doing it:
ifstream input_file("example.txt", ios::in | ios::binary)
streambuf* buf_ptr = input_file.rdbuf(); //pointer to the stream buffer
input.get(); //extract one char from the stream, to activate the buffer
input.unget(); //put the character back to undo the get()
size_t file_size = buf_ptr->in_avail();
//a value of 0 will be returned if the stream was not activated, per line 3.