【问题标题】:I/O in C ErrorsC 错误中的 I/O
【发布时间】:2013-07-29 16:12:44
【问题描述】:

我花了几个小时来寻找我在大学时遇到的这个问题的答案。我尝试通过编写一个包含两行的文件来运行它: 你好 世界 它完美地读取了文件,所以我找不到答案。非常感谢您的帮助!

一位学生编写了下一个函数,用于读取文本文件并按原样打印。

void ReadFile(FILE *fIn)
{
  char nextLine[MAX_LINE_LENGTH];
  while(!feof(fIn))
 {
 fscanf(fIn,"%s",nextLine);
 printf("%s\n",nextLine);
 }
}

这个函数的两个错误是什么?

您可以假设文件中的每一行不超过 MAX_LINE_LENGTH 个字符,并且它是一个仅包含字母字符的文本文件,并且每一行都以“\n”结尾。

谢谢。

【问题讨论】:

标签: c input output


【解决方案1】:
  1. 它会丢弃空白。尝试添加多个空格和制表符。

  2. 它可能会多次评估一个流,如果出现读取错误,则循环永远不会终止。
    见:Why is “while ( !feof (file) )” always wrong?

  3. 通过 scanf 读取字符串是危险的。没有边界检查。您可能会读到 MAX_LINE_LENGTH。(并且繁荣!Segfault)

【讨论】:

    【解决方案2】:

    主要错误是fsacnf( fIn, "%s", nextLine ) 没有扫描完整的行。 来自man page

    s 匹配一系列非空白字符;下一个指针必须是一个指向字符数组的指针,它的长度足以容纳输入序列和自动添加的终止空字节 ('\0')。输入字符串在空白处或最大字段宽度处停止,以先发生者为准。

    因此,如果您有一行“a b”,第一个 fscanf() 将只扫描“a”,第二个“b”,两者都打印在两个不同的行中。您可以使用fgets() 阅读整行。

    第二个可能是它声明“文件中的每一行不超过 MAX_LINE_LENGTH 个字符”,但nextLine 最多可以包含MAX_LINE_LENGTH-1 个字符(+ '\0')。如果您将fscanf() 替换为fgets(),则该问题变得更加重要,因为nextLine 还必须具有存储'\n''\r\n' 的容量(取决于您所在的平台)

    【讨论】:

    • 正确点,但需要加feof()不好,正确的是while(fscanf(fIn,"%s",nextLine)!= EOF){ printf("%s\n",nextLine); }
    • @grijesh 我完全同意,正确的问题是:“三个错误是什么......”。由于这是大学的问题,我怀疑忘记'\ 0'是故意犯的错误,但我当然可能是错的
    • no scanf()fgets() 都添加了 \0 @bsd 回答的 maind 问题
    • @grijesh 我从来没有说使用fgets() 可以解决长度问题,我只是说它可以用于真正逐行读取文件行。但是谢谢你的评论,我已经编辑了我的帖子以清除
    • 我的意思是scanf() 会删除空格,而fgets() 不会。
    【解决方案3】:

    正确的做法是:

    void ReadFile(FILE *fIn)
    {
      char nextLine[MAX_LINE_LENGTH];
      while(fgets(nextLine, MAX_LINE_LENGTH, fIn)) {
          printf("%s", nextLine);
      }
    }
    

    正如一些人发布的那样,使用 feof 来控制循环不是一个好主意,也不是使用 fscanf 来读取行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-24
      • 2018-05-20
      • 1970-01-01
      • 2014-10-26
      • 1970-01-01
      • 2017-09-08
      相关资源
      最近更新 更多