How can I use fread to read in a file value by value?

852 views Asked by At

I used fwrite to store some data and now I'm trying to use fread to read the data from the txt file for processing. I want to read the values individually but I can't figure out how you'd do that. This is what I have tried:

#include <stdio.h>
#include <stdlib.h>

int main () 
{
  FILE * pFile;
  long lSize;
  unsigned short * buffer;
  size_t result;

  pFile = fopen ( "myfile.txt" , "rb" );

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (unsigned short *) malloc (sizeof(unsigned short)*lSize);

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);

  printf("%uz\n", result);

  // terminate
  fclose (pFile);
  free (buffer);
  return 0;
}

The above program compiles fine but when I run it with ./a.out I get a Segmentation fault. When I run it with sudo ./a.out I don't get seg fault but nothing prints out. Any idea what I can do to fix it?

1

There are 1 answers

2
R Sahu On BEST ANSWER

Problems I see:

Allocating more memory than needed

After

lSize = ftell (pFile);

lSize is set to the number of characters in the file, not the number of unsigned shorts. Hence, you need

buffer = malloc(lSize);

See Do I cast the result of malloc?. If you are using a C++ compiler (as your C++ tag seems to imply), you need to cast the return value of malloc.

Wrong format specifier

printf("%s\n", result);

uses the wrong format specifier to print result. You need to use

printf("%zu\n", result);

That line is the most likely culprit for the segmentation fault you are seeing.


Reading objects one by one

You can certainly use:

size_t count = lSize/sizeof(short);
for ( size_t i = 0; i < count; ++i )
{
   unsigned short number;
   result = fread (&number, sizeof(unsigned short), 1, pFile);        
}

You can also use:

size_t count = lSize/sizeof(short);
for ( size_t i = 0; i < count; ++i )
{
   result = fread (buffer+i, sizeof(unsigned short), 1, pFile);        
}