Reputation: 487
I have a file like this :
name1 nickname1
name2 nickname2
name3 nickname3
And I want my programm read that file and show the name/nicknames couples.
Here is what I did :
users_file = fopen("users", "r");
while(!feof(users_file))
{
fscanf(users_file, "%s %s", &user.username, &user.name);
printf("%s | %s\n", user.username, user.nickname);
}
And here is the output :
name1 | nickname1
name2 | nickname2
name3 | nickname3
name3 | nickname3
Why is the last one repeated ? Thanks
Upvotes: 4
Views: 3520
Reputation: 122001
You need to check feof()
immediately after the fscanf()
, or, alternatively, check the return value from fscanf()
itself. The last one is repeated because fscanf()
does not read any new data into user.username
and user.nickname
due to eof being reached.
Possible fixes:
/*
* You could check that two strings were read by fscanf() but this
* would not detect the following:
*
* name1 nickname1
* name2 nickname2
* name3 nickname3
* name4
* name5
*
* The fscanf() would read "name4" and "name5" into
* 'user.username' and 'user.name' repectively.
*
* EOF is, typically, the value -1 so this will stop
* correctly at end-of-file.
*/
while(2 == fscanf(users_file, "%s %s", &user.username, &user.name))
{
printf("%s | %s\n", user.username, user.nickname);
}
or:
/*
* This would detect EOF correctly and stop at the
* first line that did not contain two separate strings.
*/
enum { LINESIZE = 1024 };
char line[LINESIZE];
while (fgets(line, LINESIZE, users_file) &&
2 == sscanf(line, "%s %s", &user.username, &user.name))
{
printf("%s | %s\n", user.username, user.name);
}
Upvotes: 3
Reputation: 21278
The feof()
function returns true if an end-of-file condition has been seen. This is probably not the case if you're reading from the file.
There are multiple ways of getting around this, something that migtht work (and is essentially what hmjd says) is:
while (fscanf(users_file, "%s %s", &user.username, &user.name) == 2) {
...
}
The return value of fscanf
is the number of sucessfully converted and assigned conversions done, so if you get an EOF while reading, this will be different from the two you expect.
Upvotes: 0
Reputation: 55583
If you change your loop to this:
while((fscanf(users_file, "%s %s", &user.username, &user.name))
{
printf("%s | %s\n", user.username, user.nickname);
}
Then it should work, note that we do not check for EOF, we let fscanf check that for us.
Upvotes: 1