pokiman
pokiman

Reputation: 986

Reading and printing an entire file in binary mode using C++

a follow up to my previous question (Reading an entire file in binary mode using C++)

After reading a jpg file in binary mode, the result of the read operation is always 4 bytes. The code is:

FILE *fd = fopen("c:\\Temp\\img.jpg", "rb");
if(fd == NULL) {
    cerr << "Error opening file\n";
    return;
}
fseek(fd, 0, SEEK_END);
long fileSize = ftell(fd);
int *stream = (int *)malloc(fileSize);
fseek(fd, 0, SEEK_SET);
int bytes_read = fread(stream, fileSize, 1, fd);
printf("%x\n", *stream);
fclose(fd);

The second last printf statement is always printing the first 4 bytes and not the entire file contents. How can I print the entire content of the jpg file?

Thanks.

Upvotes: 0

Views: 9188

Answers (3)

Chad
Chad

Reputation: 19052

You want it in C++? This opens a file, reads the entire contents into an array and prints the output to the screen:

#include <fstream>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

void hexdump(void *ptr, int buflen)
{
   unsigned char *buf = (unsigned char*)ptr;
   int i, j;
   for (i=0; i<buflen; i+=16) {
      printf("%06x: ", i);
      for (j=0; j<16; j++) { 
         if (i+j < buflen)
            printf("%02x ", buf[i+j]);
         else
            printf("   ");
      }
      printf(" ");
      for (j=0; j<16; j++) {
         if (i+j < buflen)
            printf("%c", isprint(buf[i+j]) ? buf[i+j] : '.');
      }
      printf("\n");
   }
}

int main()
{
   ifstream in;

   in.open("C:\\ISO\\ITCHOUT.txt", ios::in | ios::binary);

   if(in.is_open())
   {
      // get the starting position
      streampos start = in.tellg();

      // go to the end
      in.seekg(0, std::ios::end);

      // get the ending position
      streampos end = in.tellg();

      // go back to the start
      in.seekg(0, std::ios::beg);

      // create a vector to hold the data that
      // is resized to the total size of the file    
      std::vector<char> contents;
      contents.resize(static_cast<size_t>(end - start));

      // read it in
      in.read(&contents[0], contents.size());

      // print it out (for clarity)
      hexdump(contents.data(), contents.size());
   }
}

Upvotes: 3

user1034081
user1034081

Reputation: 618

Something like the following should do it. bytes_read() gives you the number of blocks read, in your case the block size is the file size so only one block can be read.

You should use a for loop to print the whole file. You're only printing one pointer address.

            char *stream = (char *)malloc(fileSize);
            fseek(fd, 0, SEEK_SET);
            int bytes_read = fread(stream, fileSize, 1, fd);
            for(int i=0; i<fileSize; i++){
                    printf("%d ", stream[i]);
            }

I print the chars as numbers as binary data is not readable in the console. I don't know how you wanted the data to be formatted.

This is just meant as reference to your sample. You should really consider using Chad's sample. This is a far worse solution (as mixing C/C++ far too much) just for sake of completeness.

Upvotes: 0

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234654

stream is a pointer to an int (the first element of the array you allocated1). *stream dereferences that pointer and gives you the first int.

A pointer is not an array. A pointer is not a buffer. Therefore, it carries no information about the size of the array it points to. There is no way you can print the entire array by providing only a pointer to the first element.

Whatever method you use to print that out, you'll need to provide the size information along with the pointer.

C++ happens to have a pointer + size package in its standard library: std::vector. I would recommend using that. Alternatively, you can just loop through the array yourself (which means using the size information) and print all its elements.

1Make sure the size of the file is a multiple of sizeof(int)!

Upvotes: 0

Related Questions