C++ - std::fstream read() does not read full file - c++

I would like to create a MIDI interpreter to use in a bigger project, but I'm currently facing a huge problem : It seems that in some cases, my file is not completely read, and so I don't have the whole data I need... For example, I have a file that is around 30 000 bytes long, and the fstream::read() function reads only around 3000 of them...
My code is below, if someone may have an idea...
I haven't found any similar question, but if there are any, please tell me.
std::ifstream file;
file.open("Songs/" + filename + ".mid");
if (!file.is_open())
{
std::cerr << "Failed to open file" << std::endl;
return;
}
std::vector<unsigned char> fileData;
while (file.read((char *)&c, 1))
{
fileData.push_back(c);
}
file.close();

By default, file streams use "in + out" mode to open a filestream for a text file. Try to combine exactly "in" (as you read from the file) and "binary" (as your file is not a plain text), something like this:
std::ifstream file;
file.open("Songs/" + filename + ".mid", std::ios_base::in | std::ios_base::binary);
if (!file.is_open())
{
std::cerr << "Failed to open file" << std::endl;
return;
}
std::vector<unsigned char> fileData;
while (file.read((char *)&c, 1))
{
fileData.push_back(c);
}
file.close();

Related

Reading data from file adds extra spaces

Im trying to code a program that reads a file then copies all of the data and stores it into another file. The code below does that but it adds extra bytes randomly in the file which makes the file 249KB instead of 243KB. Ive found that if i remove the "\n" it doesn't add any extra bytes but instead it removes bytes and makes it 237KB.
std::wifstream in_file("initfs_Win32", std::ios::binary);
in_file.seekg(0, std::ios::beg);
std::wstring in_data;
if (in_file.good()) {
while (std::getline(in_file, in_data))
str_buf += in_data + L"\n"
std::wofstream out_file("initfs");
out_file << str_buf;
out_file.close();
}
in_file.close();
Here is an image of the old (Right) and new (Left) files side by side:
image
If you want to copy one file into another file don't do it line by line, do it this way instead:
std::ifstream source("initfs_Win32", std::ios::binary);
if (not source.is_open())
{
std::cerr << "Error opening file" << std::endl;
}
std::ofstream destiny("initfs", std::ios::binary);
destiny << original.rdbuf();
destiny.close();

When writing from the buffer to the file, the file becomes one character larger

I use zlib library to compress data from strings and get compressed data also in strings. I load and unload compressed data using fstream. The problem is that sometimes it happens that when a line is written to a file, it becomes one byte larger and I cannot understand why this happens. I checked a row with compressed data and it has the correct size, and I can get decompressed data from it in program without writing in file. Because in the file it turns out one character more, I can no longer decompress this data. When reading such a line from a file, it is accordingly one character more as shown in a text editor.
There are "Sel" says what string size is 82.
This is example of my function which puts compressed string into file:
std::fstream file(filename, std::ios::out, std::ios::binary);
if (!file.is_open()) {
std::cout << "Unable to open file: " << filename << std::endl;
return;
}
std::stringstream someData;
...puts data in "someData"...
std::string compressedData = Compress_String(someData.str());
std::cout << "Comp string: " << compressedData << std::endl;
std::cout << "Comp size: " << compressedData.size() << std::endl;
file << compressedData;
file.close();
I'm surprised that the following line even compiles.
std::fstream file(filename, std::ios::out, std::ios::binary);
Your compiler must support a non-standard constructor. What you need is
std::fstream file(filename, std::ios::out | std::ios::binary);
// ^^^

How to read any format of file to string for further compression with Huffman algorithm

How to read any format of file(doc, pdf, jpeg)? My version works only with txt so i am not able to properly decompress file.
My function for read from input file:
std::string getDataFromFileToString(std::string &fName)
{
std::string s;
std::ifstream fr(fName, std::ios_base::in | std::ios::binary);
if (!fr.is_open())
{
std::cerr << "File \"" << fName << "\" does not exist\n";
exit(EXIT_FAILURE);
}
char c;
while(fr.get(c))
s.push_back(c);
fr.close();
return s;
}
If it only handles text files correctly, you probably need to open the files in binary mode:
change
std::ifstream fr(fName, std::ios_base::in);
to
std::ifstream fr(fName, std::ios_base::in | std::ios::binary);
and make similar changes to your output file.

Writing file doesn't work properly

I'm trying to save some of my input to a file, but it doesn't seem to work. I don't know if its the file extension or whatever, but I've tried to modify it for an hour now, however it doesn't pop-up some file in my folder.
This is how my code works (not posting everything, would be too long)
This is my function:
void mobiltelefon::savePhoneOnFile() const
{
ofstream out;
out.open("C:\\temp\\phones.txt", ios::in);
out << this->numberofphones << endl;
for (int i = 0; i < this->numberofphones; i++) {
out << this->phones[i]->getPhonename() << endl;
out << this->phones[i]->getPrice() << endl;
}
out.close();
}
This is how I call it in main:
case 7:
cout << "Save the phones on file" << endl;
fb.savePhoneOnFile();
break;
I can't see my mistake. Why doesn't the file show up a file in my folder when I try to save it?
If you are trying to open the file for writing, you should be using ios::out as the second argument
ofstream out("C:\\temp\\phones.txt", ios::out);
The various open modes are
app seek to the end of stream before each write
binary open in binary mode
in open for reading
out open for writing
trunc discard the contents of the stream when opening
ate seek to the end of stream immediately after open
Here:
ofstream out;
out.open("C:\\temp\\phones.txt", ios::in);
You don't want to have the std::ios::in flag. Why would you? You're writing to a file, not reading from it.
Explained: std::ofstream bitwise-ORs the flag argument with std::ios_base::out in its constructor and passes it to std::basic_filebuf::open. Look up out | in in that link and you have the answer. The file would need to exist to be open properly. It won't be created.
Just leave out that parameter completely and it will be defaulted to std::ios_base::out (that's what you should have had):
out.open("C:\\temp\\phones.txt");
You might as well do it at once at construction:
std::ofstream out("C:\\temp\\phones.txt");

fstream unix problem in reading

I am trying to read from binary file on UNIX. The file exists and has several data information in it.
The code looks like this:
fstrean fstrHandler;
string strFileName;
char Buf[30000];
fstrHandler.open(strFileName.c_str(), ios::in | ios::binary);
fstrHandler.seekp(0, std::ios_base::beg);
std::cout<< "Posi before read= "<< fstrHandler.tellg()<<endl; //*** Show after running 0
fstrHandler.read (Buf, 400);
std::cout<< "Posi after read= "<< fstrHandler.tellg()<<endl; //*** Show after running 0
std::cout<< " gcount ()= "<< fstrHandler.gcount ()<< << endl; //*** Show after running 0
if (fstrHandler.eof ()) {
fstrHandler.clear();
}
After the read I get that the position in file is still zero zero, but the file is not empty.
Try seekg rather than seekp, and is there 400 bytes in the file? this appears to work okay for me, if you input a file that contains more than 400 bytes. If less, then the tellg after read reports -1, but gcount() is correct.
Also, after opening the file - test to see if the file was indeed opened e.g.
if (fstrHandler)
{
// do stuff
}
else
std::cerr << "foo bar" << std::endl;