Reputation: 3075
I want to read 8byte chunks from a binary file at a time till I reach end of the file. Why doesn't this code work? What are the alternatives?
// read a file into memory
#include <iostream>
#include <fstream>
using namespace std;
int main () {
long long int * buffer;
ifstream is;
is.open ("test.txt", ios::binary );
// allocate memory:
buffer = new long long int;
// read data:
while(!is.eof())
is.read (buffer,sizeof(long long int));
is.close();
delete[] buffer;
return 0;
}
If I replace all long long int
with char
, the code works perfectly.
Ref: code adapted from www.cplusplus.com
Upvotes: 2
Views: 3627
Reputation:
The problem is !eof: it tells you whether the last operation hit eof, not whether the next will, and not whether the last failed!
Test the stream's truthiness itself (or use the fail method which is the same thing, negated), after doing the IO:
while (is.read(buffer, sizeof(long long int))) {
// use buffer
}
assert(is.fail()); // must be true
Additionally, you don't have to use new at all:
long long buffer;
// ...
is.read(reinterpret_cast<char*>(&buffer), sizeof buffer)
// the reinterpret_cast is needed in your original code too
Your source, cplusplus.com, also fails to check whether the read succeeded before using the data. In general, I find that site great for listing parameters, methods, etc. and horrible for most else.
Putting it all together, with some example output:
#include <climits>
#include <fstream>
#include <iomanip>
#include <iostream>
int main () {
using namespace std;
ifstream in ("test.txt", in.binary);
cout << hex << setfill('0');
for (long long buffer;
in.read(reinterpret_cast<char*>(&buffer), sizeof buffer);)
{
cout << setw(sizeof buffer * CHAR_BIT / 4) << buffer << '\n';
}
return 0;
}
Upvotes: 3
Reputation: 15211
Another way to do the buffer allocation is with a union. This removes the need for casting.
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
union
{
long long int n;
char ch[sizeof(long long int)];
} buffer;
ifstream is("test.txt", ios::binary);
while (is.read(buffer.ch,sizeof(buffer)))
cout << buffer.n << '\n';
return 0;
}
Upvotes: 1
Reputation: 6233
char buffer[8];
while (in.read(buffer,8)) {
long long data = *(reinterpret_cast<long long*>(buffer));
// process data
}
This is probably what you are looking for.
Upvotes: 0