【问题标题】:fgets reads too many chars than existsfgets 读取的字符过多
【发布时间】:2010-08-21 21:24:43
【问题描述】:

我有以下功能:

void writeResults(FILE* fp, FILE* fpw, Vector w, int size) {

 Vector x;

 while (1) {

       char line[MAX_DIMENSION];  //max dimension is 200

       if( (fgets(line,MAX_DIMENSION,fp)) == NULL) { //EOF
            return;
       }
       else {
           int i=0;
           while (line[i]!='\0') {
                printf("% d %c\n",i,line[i]); //print to check it
                i++;
           }
       }
 }
}

它读取的文件的行是:

1,1
2,2

但是,当我打印每个字符直到 '\0' 时,我得到以下输出:

 0 1  
 1 ,  
 2 1  
 3   
 4   
 0 2  
 1 ,  
 2 2  
 3   
 4   

有没有人知道为什么它会读取额外的 3 和 4 个字符? (文件中没有多余的空格)。

注意:文件打开方式如下:

FILE* fp = fopen(fileIn, "r");
if (fp == NULL) {
    perror("Couldn't open File");
    exit(errno);
}

【问题讨论】:

  • 不要忘记选择对您最有帮助的答案 - 突出显示 LHS 上的白色勾号(复选标记)。对所有你有有用答案的问题都这样做。这是在 SO 上成为好公民的一部分。

标签: c fgets


【解决方案1】:

不要打印 %c,打印 %d 你会看到字符 ascii 代码。你会发现字符是回车和换行。 13和10

参考http://www.asciitable.com/

【讨论】:

    【解决方案2】:

    回车、换行 - 在 Windows 上?

    如果我们知道您是如何打开文件的,将会有所帮助。如果您将其作为文本文件打开,那么您不应该看到两个额外的字符 - 只有一个用于换行符。但是,如果您将其作为二进制文件打开,它确实应该同时读取 CR 和 LF。

    如果您使用的是 Linux,如 cmets 所示,那么我们有更多可用的诊断工具。也许最简单的开始是'od -c file';这将向您准确显示文件中的内容。请注意,如果该文件曾经在 Windows 机器上,它仍然可能有 CRLF 行结尾。如果你使用'vim',它可能会告诉你文件类型是'[dos]'。

    或者,您可以将字符打印为整数(以及字符):

    printf("%d (%2d) %c\n", i, line[i], line[i]);
    

    你应该看到 49 代表 '1',50 代表 '2',44 代表 ',',10 代表换行符(LF,'\n'),还有其他的 - 这就是谜(但它会为 CR 显示 13)。


    CR 是 C 源代码中的 \r 字符。用于指示打印头应移回行首(打印机滑架返回行首); LF 或换行将纸张向上滚动一行。 Windows 和 MS-DOS 都使用 CRLF (curr-liff) 序列来指示行尾; Unix 总是只使用 LF,也就是换行符或 NL; MacOS 9 及更早版本仅使用 CR。

    【讨论】:

    • 我真的不知道什么是回车...我在linux上运行
    • OK - 在 Linux 上,这不太可能成为问题。我会在我的回答中添加一些建议。
    • 用 openinig 流更新了问题......但是你没事......谢谢你的回答
    • 你是对的: 1 , 1 \r \n 2 , 2 \r \n 这是我从 od-c 得到的有没有办法绕过它?一个不会从文件中读取这个的函数?
    • @Mike:没有简单的方法可以避免阅读这些字符。然而,简单地忽略它们是完全合法的。这是大多数人会做的。或者在进一步处理之前简单地将行尾:换行,或者在这种情况下,在每行的末尾加上 CRLF。 (Perl 有一个 chomp 语句正是这样做的。)
    【解决方案3】:

    我认为您的输入文件包含-

    1,1
    [SPACESPACE]
    2,2
    [SPACESPACE]
    

    所以第一次 fgets 读起来像-

    line{'1',',','1','',''}
    

    第二次阅读

    line{'2',',','2','',''}
    

    这就是为什么,你得到了你指定的输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 2018-05-28
      • 1970-01-01
      • 2017-02-11
      • 2017-06-24
      • 1970-01-01
      相关资源
      最近更新 更多