Pointers in C with binary file

I am reading the contents of the file using fread into an char array. But I am not sure why it is not getting printed in the output. Here is the code:

void getInfo(FILE* inputFile)
{
   char chunk[4];
   int liIndex;
   for (liIndex = 0 ; liIndex < 4 ; liIndex++)
   {
      fread(chunk, sizeof(char), 4, inputFile);
   }
   printf("\n chunk %s", chunk);
}

Output prints nothing at all. Where am I going wrong?

Regards , darkie

Answers


You cannot print a binary file using printf. printf will treat the binary blob as a null-terminated string, so any '\0' byte that happens to be in your chunk will end the "string".

To write the chunk to stdout in full, use fwrite:

fwrite(chunk, sizeof(char), 4, stdout);

Move the printf into the loop. As it is, you're only printing the last chunk read.

Edit: I read the question but not the title, apparently. You'll have to do this and switch to fwrite like Thomas said.


In my opinion, fread and fwrite are just adding a layer of confusion.

Try byte-oriented input and output functions instead, since 4-byte chunks aren't much better than not using chunks at all, and you can't make mistakes in code that you don't write.

int ch; 
while ((ch = getc(inputFile)) != EOF)
   putchar(ch); 

But I think the real issue here is that you might not completely understand what you're asking for. You are reading binary data, and then trying to print it out as character data; many arbitrary byte values don't correspond to any printable characters. What do you expect to see for those bytes?

A more informative approach might be to print out the integer value of each byte, as well as the character it represents. This will let you see clearly when there are unprintable characters in your file.

eg,

void func(FILE *s)
{
   int ch;
   while ( (ch = getc(s)) != EOF )
      printf("%d -> %c\n", ch, ch);
}

When I run this program snippet on a file containing one of each byte, it becomes clear that many values have no meaning when interpreted as a character:

[snip...]
29 ->
30 ->
31 ->
32 ->
33 -> !
34 -> "
35 -> #
36 -> $
37 -> %
38 -> &
39 -> '
[...more snipping]

Deconstructing your source code a bit:

void getInfo(FILE* inputFile) 
{ 
   char chunk[4]; 
   int liIndex; 
   for (liIndex = 0 ; liIndex < 4 ; liIndex++) 
   { 
      fread(chunk, sizeof(char), 4, inputFile); 

You're reading 4 bytes at a time, repeated 4 times; that means when the loop exits, you've read 16 bytes, and chunk contains bytes 12-16. Is that what you intended? If you just want to read the first four bytes, ditch the loop and just call fread once. If you want to read and print the first 16 bytes, then you'll need to move the output statement into the loop as well.

As others have mentioned, don't hardcode the 4; use sizeof chunk instead.

   } 
   printf("\n chunk %s", chunk); 
} 

Remember that the %s conversion specifier expects the corresponding argument to point to a 0-terminated sequence of printable characters, so chunk[0] through chunk[2] need to be printable (i.e., isprint(chunk[i]) == 1), and chunk[3] had better always be a 0, or you could get some strange output. Since that tends to rarely be the case in binary files, you may want to change how you write that output.

Here's how you could print the individual bytes as integer values:

printf("chunk: ");
for (i = 0; i < sizeof chunk; i++)
  printf("%02x ", chunk[i];
putchar('\n');

Need Your Help

Rails[RSpec]: put :update, no route matches :id => nil

ruby-on-rails ruby-on-rails-4 rspec devise routes

Very strange error. I am writing RSpec tests for a subgroup controller, which is in a many-to-one relationship with group. group accepts nested attributes for subgroup. I used scaffolding, and I've...

Is it possible to host a bare Git repository using Dropbox, to share code?

git dropbox

I realize that there are similar questions, but my question is slightly different: I'm wondering whether sharing a bare repository via a synchronized Dropbox folder on multiple computers would work...