0

I am trying to read and write some boolean grids to a file using stdio.h. The user inputs a number nx (from 1 to 10, generally) and the program generates a list of nx by ceil(nx / 2) boolean grids (ceil(nx / 2) is ny). The grids themselves are stored in __int64s, so this grid (f is false and T is true):

ffTT
fTfT

would be 172 (10101100).

The end list of grids is outputted to a binary file.

My code:

std::vector<__int64> grids;

...

FILE *cFile;
if (fopen_s(&cFile, ("grid_" + std::to_string(nx) + "_c.bin").c_str(), "wb") != 0) return;

for (int i = 0; i < grids.size(); i++) {
    fwrite(&grids[i], (int) ceil((nx * ny) / 8), 1, cFile);
}

fclose(cFile);

This part works fine.


However, when I try to read from a file, all of the grids are -858993460, regardless of size, although it gets the number of grids correct. My code for reading:

FILE *cFile;
if (fopen_s(&cFile, ("grid_" + std::to_string(nx) + "_c.bin").c_str(), "rb") != 0) return;

fseek(cFile, 0, SEEK_END);
long size = ftell(cFile);

int grids = size / ((nx * ny) / 8);

for (int n = 0; n < shapes; n++) {
    __int64 data;
    fread(&data, (int) ceil((nx * ny) / 8), 1, cFile);
    printf("%i\n", data);
}

fclose(cFile);

What am I doing wrong?


If you need any more information to answer, leave a comment and I'll give it to you.

Thanks in advance!

2
  • What's the purpose of using ceil here? Commented Apr 29, 2015 at 20:47
  • @RSahu It makes the output an integer number of bytes. Not using ceil would round down, so 603 would end up as 91. Commented May 1, 2015 at 0:50

2 Answers 2

3

Problem

The problem is that you are moving the FILE* to the end of the file using:

fseek(cFile, 0, SEEK_END);

And then, you are trying to read the data without going back to the start of the file.

You are not checking the returned value of:

fread(&data, (int) ceil((nx * ny) / 8), 1, cFile);

to check whether the read was successful or not.

Fix

Add the line

fseek(cFile, 0, SEEK_SET);

to rewind the file.

Always check the return value of reading operations.

if ( fread(&data, (int) ceil((nx * ny) / 8), 1, cFile) == 1 )
{
   // Successful read.
   // Use the data
}
Sign up to request clarification or add additional context in comments.

Comments

0

I think you are using fwrite and fread in strange ways. Please do

 fwrite(&gris[i], sizeof(__int64), 1, cFile);

for dump and

 fread(&data, sizeof(__int64), 1, cFile);

for recovering.

4 Comments

sizeof(__int64) would always return 8. I am shooting for the smallest filesize possible, therefore I use (int) ceil((nx * ny) / 8), the smallest possible size.
Yes, but for storing a single item you must specify at least 1 byte. The element size is independent of array size.
Each array is nx by ny
yes but you pass &grids[i] (that's a __int64*) when writting and fwrite takes account of the bytes of the element: the second parameter cannot be used for write a single bit, the minimum is 1 byte. cplusplus.com/reference/cstdio/fwrite The same happens for fread.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.