Read and display all file bytes in C++

Viewed 280

I'm trying to show all the bytes in a .DAT file. I'm completely new to programming and I managed to find how to display the file size correctly but every output byte that I get are 0s even if in HxD the bytes aren't all zero.

What I get:

size is: 11
0000000000000000000000

What I should get:

size is: 11
48656C6C6F20776F726C64

Code:

#include <iostream>
#include <fstream>
#include <vector>
#include <fstream>
#include <iterator>
#include <iomanip>
using namespace std;

int main () {
  //open file and get size
  streampos begin,end;
  ifstream myfile ("TRPTRANS.DAT", ios::binary);
  begin = myfile.tellg();
  myfile.seekg (0, ios::end);
  end = myfile.tellg();
  int n;
  n=(end-begin);
  cout << "size is: " << n<<endl;

  //read file
  vector<char> randomBytes(n);
  myfile.read(&randomBytes[0], n);

  //display bytes
  for (auto& el : randomBytes)
  cout << setfill('0') << setw(2) << hex << (0xff & (unsigned int)el);
  cout << '\n';

  return 0;
}

Can someone help me fix this and show the bytes correctly thanks

2 Answers

First, you seek to the end of the file:

  myfile.seekg (0, ios::end);

But then you don't go back to the beginning, so the read call tries to read from the end of the file, which fails.

Try adding this before the read call:

  myfile.seekg (0, ios::beg);

And also check the error status afterwards:

  if (!myfile) {
    cerr << "could only read " << myfile.gcount() << " bytes\n";
  }

Here is a simple code that avoids looking at file size, using iterator to read the bytes into a char vector.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <iterator>
#include <vector>

using namespace std;
int main()
{  
    ifstream input("TRPTRANS.DAT", ios::binary);
    //read bytes into vector
    vector<char> bytes(
    (istreambuf_iterator<char>(input)),
    (istreambuf_iterator<char>()));

    input.close();

    //print bytes as hex
    for (vector<char>::const_iterator i = bytes.begin(); i != bytes.end(); ++i)
        cout << setfill('0') << setw(2) << hex << (0xff & (unsigned int) *i) << endl;

    return 0;
}

If you are using the C++11 standard (or later) then you can use the auto keyword to help the readability:

for (auto i = bytes.begin(); i != bytes.end(); ++i)
Related