4

私はこのようなファイルを持っています:

name1 nickname1
name2 nickname2
name3 nickname3

そして、私のプログラムにそのファイルを読み取って、名前/ニックネームのカップルを表示してもらいたいです。

これが私がしたことです:

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

そしてここに出力があります:

 name1 | nickname1 
 name2 | nickname2      
 name3 | nickname3 
 name3 | nickname3

なぜ最後のものが繰り返されるのですか?ありがとう

4

3 に答える 3

3

feof()の直後に確認fscanf()するか、またはそれ自体からの戻り値を確認する必要がありfscanf()ます。eofに到達したために新しいデータが読み込まれfscanf()ないため、最後のデータが繰り返されます。user.usernameuser.nickname

考えられる修正:

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

また:

/*
 * 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);
}
于 2012-03-08T16:10:55.227 に答える
1

ループをこれに変更した場合:

while((fscanf(users_file, "%s %s", &user.username, &user.name))
{
    printf("%s | %s\n", user.username, user.nickname);
}

次に、動作するはずです。EOFをチェックしないことに注意してください。これは、fscanfにチェックさせます。

于 2012-03-08T16:12:14.370 に答える
0

feof()ファイルの終わりの状態が確認された場合、関数はtrueを返します。ファイルから読み取っている場合、これはおそらく当てはまりません。

これを回避する方法は複数ありますが、migthtが機能する(そして本質的にhmjdが言うことです)のは次のとおりです。

while (fscanf(users_file, "%s %s", &user.username, &user.name) == 2) {
  ...
}

の戻り値fscanfは、正常に変換され、割り当てられた変換が行われた数です。したがって、読み取り中にEOFを取得した場合、これは期待した2つとは異なります。

于 2012-03-08T16:18:12.743 に答える