C fgets读取的字符数过多

C fgets读取的字符数过多,c,fgets,C,Fgets,我有以下功能: 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; } e

我有以下功能:

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

回车,换行窗口

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

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

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

你应该看到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.

回车,换行-在Windows上

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

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

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

你应该看到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。

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


请参阅

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


请参阅

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

1,1
[SPACESPACE]
2,2
[SPACESPACE]
所以第一次FGET读起来像-

line{'1',',','1','',''}
第二次读

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

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

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

1,1
[SPACESPACE]
2,2
[SPACESPACE]
所以第一次FGET读起来像-

line{'1',',','1','',''}
第二次读

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

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

我真的不知道什么是回车。。。我在linuxOK上运行—在Linux上,这不太可能成为问题。我会给我的答案添加一些建议。用openinig stream更新了问题。。。不过你没事。。谢谢你的回答你是对的:1,1\r\n 2,2\r\n这是我从od-c得到的,有办法绕过它吗?一个不会从文件中读取这些字符的函数?@Mike:没有简单的方法可以避免读取字符。然而,完全无视它们是完全合法的。大多数人都会这么做。或者在进一步处理之前,简单地在每一行的末尾加上换行符或CRLF。(Perl有一个
chomp
语句就是这样做的。)我真的不知道什么是回车。。。我在linuxOK上运行—在Linux上,这不太可能成为问题。我会给我的答案添加一些建议。用openinig stream更新了问题。。。不过你没事。。谢谢你的回答你是对的:1,1\r\n 2,2\r\n这是我从od-c得到的,有办法绕过它吗?一个不会从文件中读取这些字符的函数?@Mike:没有简单的方法可以避免读取字符。然而,完全无视它们是完全合法的。大多数人都会这么做。或者在进一步处理之前,简单地在每一行的末尾加上换行符或CRLF。(Perl有一个
chomp
语句正好可以做到这一点。)不要忘记选择对您帮助最大的答案-突出显示LHS上的白色勾号(复选标记)。对所有你有有用答案的问题都这样做。这是成为一个好公民的一部分。别忘了选择对你最有帮助的答案——在左侧突出显示白色勾号(复选标记)。对所有你有有用答案的问题都这样做。这是做一个好公民的一部分。