#Trouble reading integers from a binary file

59 messages · Page 1 of 1 (latest)

glass cradle
#

I need to read a 49 character string and the sequence of integers that come after it in layout.dat. I wrote this code as a way to test a way to do that. It outputs the string properly, but the ints are completely wrong.

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

int main() {
FILE *file;
char nome[50];
int num;

int counter = 1;

file = fopen("layout.dat", "rb");

fread(&nome, sizeof(char), 49, file);
printf("%s\n", nome);

while (!feof(file))
{
    for (int i = 0; i < 3; i++)
    {
        fread(&num, sizeof(int), 1, file);
        printf("%d ", num);
    }
    printf(" obstacle number %d", counter);
    counter++;
    printf("\n");
}

}`

barren voidBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

bronze fulcrum
#

fread(&num, sizeof(int), 1, file); this is a potentially wrong way to read an int depending on endianness

half plover
#

The values in the binary file look to be in big-endian byte order, where as your CPU probably uses little-endian

teal locust
#

yeah.. throw your computer away and buy a big endian one. yamikek

dim grove
#

ntohl() or variants thereof could work here.

glass cradle
teal locust
#

cpu specficific .. not OS

glass cradle
#

Currently I'm just reading them as ints and printing them out, but the ints in the binary file are supposed to go into an array of structs. A classmate is telling me that he was having a similar issue and sending the ints directly into a struct solved it, so I guess I'll try it out and see if it changes anything

bronze fulcrum
#

you should try reading them byte-wise into an array and then constructing an int from those values

teal locust
bronze fulcrum
#

you usually define the endianness of the data format

#

and that way everyone can be happy because if you're on the wrong endianness cpu you know to convert

#

instead of you having to know where the data came from

#

but also seems unlikely that your VM would randomly be emulating a different endianness

glass cradle
#

this works perfectly for some reason dawg

teal locust
#

then you probably have endian correct... OR .width .he are already 1 byte

bronze fulcrum
#

what

#

if this works then what you were doing before was definitely wrong

#

every time you read into this struct you read the name

#

which you werent doing before

glass cradle
#

previously I was reading the name outside the loop with fread(&nome, sizeof(char), 49, file);

bronze fulcrum
#

whats the type of this struct

#

like can we see the definition

#

to know if it should have made a difference

glass cradle
#

oh yeah my bad

bronze fulcrum
#

oh

#

OH

#

I SEE IT

#

its not the ints its the name

#

probably

#

how many bytes is name encoded as?

teal locust
#

is fread like network stuff in that it can return less than asked for num of bytes?

bronze fulcrum
#

Im thinking that the name is actually 50 bytes in the file

#

they read 49 for the string

#

and then leave the last one

#

which is why reading it from the struct works, because the 50 bytes array reads 50 bytes when its part of the struct and they didn't handle that differently

teal locust
#

yeah,

#

scanf(%s,%d.. aint going to read the 10 nulls on the end of the 40char string

glass cradle
bronze fulcrum
#

yeah looks like your file isnt the format you thought

#

even though what you showed us looks like it is tbf

#

but only because you highlighted it

teal locust
#

layout.dat looks like 49 bytes for name

#

3 rows of 16 + 1 char. then 4 byte ints

bronze fulcrum
# glass cradle the name and the first two ints get sent into the struct below, and the plan is ...
fread(..., sizeof(structCabecalho), 1, file);
```is equivalent to
```cpp
fread(..., sizeof(char), 50, file);
fread(..., sizeof(int), 1, file);
fread(..., sizeof(int), 1, file);
```what you were doing before is
```cpp
fread(..., sizeof(char), 49, file);
fread(..., sizeof(int), 1, file);
fread(..., sizeof(int), 1, file);
```perhaps you can see the difference ![yamikek](https://cdn.discordapp.com/emojis/644618999857938492.webp?size=128 "yamikek")
glass cradle
#

I KNEW IT WAS THE NAME THAT WAS MESSING IT UP ange

glass cradle
#

I've implemented the function that reads all the ints, but for some reason this part detects an error even though when I comment out the exit(1), it prints out the information perfectly

`while (!feof(layoutDAT))
{
if (fread(&obstacleArray[obstacleCounter], sizeof(obstacleArray[obstacleCounter]), 1, layoutDAT))
{
obstacleCounter++;
}else
{
printf("Erro a ler obstáculos");
//exit(1);
}

    }`
bronze fulcrum
#

if is entered if the value != 0

#

hmm

#

wait

#

okay I read it again lol

#

welp idk

dim grove
#

Spitballing....
Upon reading the last obstacle from file, would feof() still return zero on the next time of asking?

From cppref:

This function only reports the stream state as reported by the most recent I/O operation

The last read succeeded, did it not?
So the loop tries to read one more object from file, which does not exist.
With the exit() enabled, your program bombs out even though it has successfully read all objects.

#

If correct (big IF) then the code could/should possibly read instead...

while (fread(&obstacleArray[obstacleCounter], sizeof(obstacleArray[obstacleCounter]), 1, layoutDAT))
{
    obstacleCounter++;
}
odd sparrow