If my fgets is in a while loop, it only returns half the string. If it's in a for loop, it returns the whole string.. Any idea why?
Code below:
FILE *fp; // File pointer
char filename[] = "results.tsv";
fp = fopen(filename, "r"); // Open file argv[1] for READ
char s[4096];
int num = atoi(fgets(s, sizeof(s), fp)); // Get first line (number of units in file)
int i;
for(i = 0; i < num; i++)
{
printf("%s", fgets(s, sizeof(s), fp)); // Prints everything
}
while (fgets(s, sizeof(s), fp) != NULL) // Loop until no more lines
{
printf("%s\n", s); // Only prints the x's
}
fclose(fp); // Close file
And the files contents:
1
xxxxxxxx yyyy eee
Where the big spaces are tabs (\t).
If I run it, I get:
For loop only:
xxxxxxxx yyyy eee
While loop only:
xxxxxxxx
Thanks.
As already diagnosed, your code 'works for me'. Here's the SSCCE I created for it. If invoked with no arguments, it uses the while
loop. If invoked with any arguments, it uses the for
loop. Either way, it works correctly for me. Note that the code doesn't use the return value from fgets()
directly; it checks that the input operation succeeded before doing so. It also echos what it is doing and reading as it goes.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *fp;
char filename[] = "results.tsv";
if ((fp = fopen(filename, "r")) == 0)
{
fprintf(stderr, "%s: failed to open file %s\n", argv[0], filename);
exit(1);
}
char s[4096];
if (fgets(s, sizeof(s), fp) == 0)
{
fprintf(stderr, "Premature EOF\n");
exit(1);
}
int num = atoi(s);
printf("Num lines: %d\n", num);
if (argc > 1)
{
printf("For loop:\n");
for (int i = 0; i < num; i++)
{
if (fgets(s, sizeof(s), fp) == 0)
{
fprintf(stderr, "Premature EOF\n");
exit(1);
}
printf("%d: %s", i+1, s);
}
}
else
{
int i = 0;
while (fgets(s, sizeof(s), fp) != NULL)
{
printf("While loop:\n");
printf("%d: %s", ++i, s);
}
}
fclose(fp);
return 0;
}
If you use this code and it fails on your system, then you could submit your evidence. Amongst other things, you should identify the platform on which you're working, and you should give a hex dump (or equivalent) of the data in the file results.tsv
. The data file I used, for example, contained the bytes:
0x0000: 31 0A 78 78 78 78 78 78 78 78 09 79 79 79 79 09 1.xxxxxxxx.yyyy.
0x0010: 65 65 65 65 0A eeee.
0x0015: