Vai*_*wal 6 c string fgets carriage-return
我正在运行以下代码:
#include<stdio.h>
#include<string.h>
#include<io.h>
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;
}
Run Code Online (Sandbox Code Playgroud)
text.txt包含: I am a boy\r\n
由于我在Windows上,它需要\ r \n作为新行字符等等,如果我读这从一个文件应该存储"I am a boy\n\0"在str,但我得到"I am a boy\r\n".我正在使用mingw编译器.
行为取决于c库实现以及传递给哪种模式fopen.请参阅MSDN文档中的这个引用(在MSDN上的fopen fopen):
b - 以二进制(未翻译)模式打开; 涉及回车符和换行符的翻译被抑制.
意味着,如果您使用Microsoft c库,并打开省略'b'的文件,则将从流中删除回车符.
由于您正在使用mingw,您的编译器可能会链接到遵循POSIX标准的GNU c库.这就是GNU文档所说的内容fopen (fnn在gnu.org上):
opentype中的字符'b'具有标准含义; 它请求二进制流而不是文本流.但这对POSIX系统(包括GNU系统)没有任何影响.
结论:你省略了'b'模式char,它以文本模式打开你的流.你在Windows上,但使用GNU c库,它在文本和二进制模式之间没有区别.这就是fgets读取回车和换行的原因.
由于我在Windows上,它需要\ r \n作为新行字符...
这个假设是错误的.C标准将回车和新线视为两种不同的东西,如C99§5.2.1/ 3(字符集)所示:
[...]在基本执行字符集中,应有代表警报,退格,回车和换行的控制字符.[...]
该fgets函数描述如下,在C99§7.19.7.2/ 2:
fgets函数最多读取一个小于n指定的字符数,该字符串由stream指向s指向的数组的流指定.在换行符(保留)或文件结束后不会读取其他字符.在读入数组的最后一个字符后立即写入空字符.
因此,遇到字符串时I am a boy\r\n,符合要求的实现应该读取该\n字符.没有可能的理由为什么实施应该\r基于平台丢弃.