由fgets回车

我正在运行以下代码:

#include #include #include int main(){ FILE *fp; if((fp=fopen("test.txt","r"))==NULL){ printf("File can't be read\n"); exit(1); } char str[50]; fgets(str,50,fp); printf("%s",str); return 0; } 

text.txt包含: I am a boy\r\n

由于我在Windows上,它需要\ r \ n作为一个新的行字符,所以如果我从一个文件中读取它,它应该在str存储"I am a boy\n\0" ,但我得到"I am a boy\r\n" 。 我正在使用mingw编译器。

由于我在Windows上,它需要\ r \ n作为新行字符…

这个假设是错误的。 C标准将回车和新线视为两种不同的东西,如C99§5.2.1/ 3(字符集)所示:

[…]在基本执行字符集中,应有控制字符,表示警报,退格,回车和换行。 […]

f99函数描述如下,在C99§7.19.7.2/ 2中:

fgets函数最多只读取一个小于n指定的字符数,该值由stream指向的流指向s指向的数组。 在换行符 (保留)或文件结束不会读取其他字符 。 在读入数组的最后一个字符后立即写入空字符。

因此,当遇到字符串I am a boy\r\n ,符合要求的实现应该读取\n字符。 实现应该基于平台丢弃\r是没有可能的理由。

行为取决于c库实现以及传递给fopen模式。 请参阅有关fopen的MSDN文档中的此引用(在MSDN上的fopen ) :

b – 以二进制(未翻译)模式打开; 涉及回车符和换行符的翻译被抑制。

意味着,如果您使用Microsoft c库,并打开省略’b’的文件,则将从流中删除回车符。

由于您正在使用mingw,您的编译器可能会链接到遵循POSIX标准的GNU c库。 这就是GNU文档中关于fopen说法(fnn在gnu.org上) :

opentype中的字符’b’具有标准含义; 它请求二进制流而不是文本流。 但这对POSIX系统(包括GNU系统)没有任何影响。

结论:您省略了’b’模式char,它以文本模式打开您的流。 你在Windows上,但使用GNU c库,它在文本和二进制模式之间没有区别。 这就是fgets读取回车和换行的原因。