3

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?

Fortuna Iwasaki
  • 141
  • 1
  • 2
  • 11

1 Answers1

1

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);        
}
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • But the values that are written to the file are of type unsigned short. When I do what you said I just get a bunch of `1z` printed out to the screen. – Fortuna Iwasaki Dec 27 '16 at 16:13
  • The return value of `fread` is the number of objects read. If you read one object at a time, the value of `result` will be `1`. You are seeing `1z` as output due to an error in the format I had suggested. It needed to be `"%zu"` instead of `"%uz"`. I fixed the error in the answer. – R Sahu Dec 27 '16 at 18:22