Frage

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

War es hilfreich?

Lösung

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);
}

Andere Tipps

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.

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top