I am having difficulty with using the fread() function to read values from a file for a very specific and unlikely use case. This sounds really stupid, but an assignment I am working on requires me to do a partial read of items in a file.
My file name is "test_file.txt", and it's written in the following format, with one integer per line:
23
4
10
My code snippet, which is meant to process the above three bytes at a time, looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
int value = 0;
char buffer[3];
FILE* channel_file = fopen("test_file.txt", "rb");
while(fread(&buffer, sizeof(char), sizeof(buffer), channel_file) > 0) {
sscanf(buffer, "%d", &value);
printf("%d \n", value);
memset(buffer, 0, sizeof(buffer));
}
}
Since I am reading the file 3 bytes at a time, I was expecting it to look like this:
23\n
4\n1
0\n
which does seem to be the case (since \n counts as a byte). Printed, I wanted to see
23
41
0
However, when I try to print these values using the code above, I only get this:
23
4
I have tried a variety of different parameters in the fread() function itself, but none of them give the expected output. I was hoping someone more familiar with C and string parsing could help.
** EDIT: Posted a solution below. The solution is prone to undefined behavior since buffer and str are not null terminated. A mechanism for adding null termination to the buffer and str char array would improve the solution here.
On review, the approach below, given OP's file input of
"23\n4\n10\n", prints:This is not OP's goal of:
Seems I mis-understood OP's goal. Making answer wiki for reference.
It appears OP is obliged to use
fread()for input. Sigh.Consider using
fread()to read in up to so many characters. Maybe up to 3 in this case.Open the file in text mode to handle systems that use
"\r\n"as a single'\n'.fopen("test_file.txt", "rb")-->fopen("test_file.txt", "r").Make the buffer one larger so we can append a null character and process
bufferas a string.sscanf(buffer...expects a string.No need for
&buffer.bufferitself will convert to the type of&buffer[0].Use
" %n"to store how many characters were consumed converting the string into anint. Use that to adjust how many characters to read in the nextfread().No need for a space before printing a
'\n'.Good practice: check return value from
sscanf().A more advanced approach would use a much larger buffer and look for multiple
intin the string. We could then reduce the wastefulmemmove().It is more robust to use
strtol()thansscanf(..."%d ...Leave those for a later day.