I am trying to read data from binary file to an std::string.Here is what I have tried at first.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
string my_str(5, '\0');
file.read(my_str.c_str(), 5);
cout << "String = " << my_str<< endl ;
}
And the compiler gave the error :
error: invalid conversion from ‘const char*’ to ‘std::basic_istream<char>::char_type* {aka char*}’ [-fpermissive]
file.read(my_str.c_str(), 5);
As far as I understand, c_str() returns a const pointer which cannot be used in read method, so I changed my approach a little bit(which you can see below). Is there a better way to do this ?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
string my_str(5, '\0');
char buffer[6];
file.read(buffer, 5);
buffer[5] = '\0';
my_str = string(buffer);
cout << "String = " << my_str<< endl ;
}
ps : forgive me if I could not make myself clear, this is my first time here :)
C++ read binary file is a file Input/Output operation that is handled by the stream-based interface of the C++ Standard Template Library. You’ll need to utilize the std::fstream class for creating a file stream object first, and then the contents of it can be read using different methods based on the needs of the solution.
After the fopen returns the file pointer, we can call the fread function to read binary stream. fread takes four arguments, the first of which is the void pointer to the location where the read bytes should be stored. The next two arguments specify the size and number of the data items that need to be read from the given file.
This is not the answer. stdin is a buffered input stream, and fread () will read buffered data, and on Windows it will be reading in text mode and convert to a single character, which will be bad for binary data. I don't know what OS you are running, but you typically cannot "open stdin in binary".
You can also convert binary to text: "convert to hex text string" and "uuencode base 64" are two common ways to do this. You'll want to read the bytes as numbers (of type long long probably). Then you can print those using formatting specifiers like this:
In C++11, the way to get a non-const
pointer to the string's data is:
file.read(&my_str[0], 5);
C++17 will introduce non-const
data()
for this as well:
file.read(my_str.data(), 5);
another way, using standard algorithms:
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm>
#include <iterator>
using namespace std;
int main(int argc, char const *argv[])
{
fstream file("output.bin" , ios::out | ios::binary | ios::in);
auto my_str = string();
copy_n(istream_iterator<char>(file),
5,
std::back_inserter(my_str));
cout << "String = " << my_str<< endl ;
}
std::string
is specially designed to work with strings and with c-style strings as well, so this fact will work against you in this situation. For example your code:
char buffer[6];
file.read(buffer, 5);
buffer[5] = '\0';
my_str = string(buffer);
what is wrong with it? You are reading binary data and who guarantees that there won't be '\0' byte there? You can fix it by:
my_str = string(buffer,5);
but this shows the point - std::string
as a buffer is not a good choice. So you better use std::vector<char>
or even better std::vector<uint8_t>
which has method data()
but will not implicitly convert from c-string, output to std::ostream
etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With