【问题标题】:Reading names in a file in C在 C 中读取文件中的名称
【发布时间】:2012-03-08 16:07:43
【问题描述】:

我有一个这样的文件:

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

为什么最后一个重复? 谢谢

【问题讨论】:

    标签: c scanf feof


    【解决方案1】:

    您需要在fscanf() 之后立即检查feof(),或者检查fscanf() 本身的返回值。重复最后一个是因为fscanf() 没有将任何新数据读入user.usernameuser.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);
    }
    

    【讨论】:

      【解决方案2】:

      如果您将循环更改为:

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

      然后它应该可以工作了,注意我们不检查 EOF,我们让 fscanf 为我们检查。

      【讨论】:

        【解决方案3】:

        如果发现文件结束条件,feof() 函数将返回 true。如果您从文件中读取,则可能不是这种情况。

        有多种方法可以解决这个问题,可能有效的方法(本质上就是 hmjd 所说的)是:

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

        fscanf 的返回值是成功转换和分配完成的转换次数,因此如果您在读取时收到 EOF,这将与您预期的两个不同。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-11-02
          • 2020-03-16
          • 1970-01-01
          • 2015-07-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多