由fgets回车

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编译器.

Edu*_*rch 8

行为取决于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读取回车和换行的原因.


net*_*der 5

由于我在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基于平台丢弃.