Чтение имен в файле на C - PullRequest
       35

Чтение имен в файле на C

4 голосов
/ 08 марта 2012

У меня есть такой файл:

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

Почему последний повторяется? Спасибо

Ответы [ 3 ]

3 голосов
/ 08 марта 2012

Вам необходимо проверить feof() сразу после fscanf(), или, альтернативно, проверить возвращаемое значение из fscanf().Последний повторяется, потому что fscanf() не считывает новые данные в user.username и user.nickname из-за достижения eof.

Возможные исправления:

/*
 * 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);
}
1 голос
/ 08 марта 2012

Если вы измените свой цикл на это:

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

Тогда это должно сработать, обратите внимание, что мы не проверяем EOF, мы позволяем fscanf проверить это для нас.

0 голосов
/ 08 марта 2012

Функция feof() возвращает true, если было замечено условие конца файла.Вероятно, это не тот случай, если вы читаете из файла.

Есть несколько способов обойти это, что работает с Migtht (и, по сути, так говорит hmjd):

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

Возвращаемое значение fscanf - это число успешно преобразованных и назначенных преобразований, поэтому, если вы получите EOF во время чтения, это будет отличаться от ожидаемых вами значений.

...