Ok, so I suggest that you forget about linked lists. Just stick to the first problem: reading data from a binary file.
The text of the problem is unclear about the size of the objects, so let's assume that it says: "There is a binary file which contains widgets composed by a 32 bit integer (little endian) and an 8 bit number representing an ASCII character. Dump all the widgets to stdout
one per line representing the integer in base 10 followed by a space and then the character".
Let's assume that your int
is 32 bit little endian and your char is a signed byte, i.e. let's assume you are on one of the 99.9% of the machines in the world.
Now you have to read the widgets, that is an int and a char. There are usually two functions you have to chose from when reading: fscanf
and fread
. The first one reads from data formatted for humans to read, while the second one reads bytes as they are from a file. Which one do you need now? the second one, so we need to use that.
In your code you write
while (!feof(fptr))
This is always wrong. The only correct way for reading a file is:
while (1) {
// Read
// Check
// Use
}
Then you can find a way to read and check in the while condition, but believe me: write it this way the first time.
So lets populate the above template. To check if fread
succeeded you need to check if it returned the number of elements you asked for.
while (1) {
int i;
char c;
// Read
int ok1 = fread(&i, 4, 1, fptr);
int ok2 = fread(&c, 1, 1, fptr);
// Check
if (ok1 != 1 || ok2 != 1)
break;
// Use
printf("%d %c\n", i, c);
}
Of course you can pack this in the while condition, but I don't see a reason for that.
Now I'd test this with your input and with a good debugger and check if all the data in the file gets printed out. If everything is ok, you can move on to the rest of the problem, that is putting these widgets in a linked list.
Here I assumed that you didn't learn struct
s yet. If this is not the case, you can work with them:
struct widget {
int i;
char c;
};
[...]
while (1) {
struct widget w;
// Read
int ok1 = fread(&w.i, 4, 1, fptr);
int ok2 = fread(&w.c, 1, 1, fptr);
// Check
if (ok1 != 1 || ok2 != 1)
break;
// Use
printf("%d %c\n", w.i, w.c);
}
Don't be deluded by the fact that the widget has the same structure of your data on file. You cannot trust that
fread(&w, 5, 1, fptr); // No! Don't do this
will read your data correctly. When making a struct, the compiler can put all the space it want between fields, so I wouldn't be surprised if sizeof(widget)
returned 8.
Disclaimer: I wrote the code directly on the browser and didn't check it!