[英]Reading files with DOS line endings using fgets() on linux
我有一个在运行时收到的DOS行结尾的文件,所以我无法将行结尾转换为UNIX样式的离线。 此外,我的应用程序在Windows和Linux上运行。 我的应用程序在文件上执行fgets()
并尝试逐行读取。
在Linux上每行读取的字节数也会占2个尾随字符(\\r \\n)
还是只包含(\\ n) ,而\\ r \\ n会被底层系统丢弃?
编辑:
好吧,所以在Linux上读取文件时会保留行结尾,但我遇到了另一个问题。 在Windows上,以“r”或“rb”打开文件的行为有所不同。 与Linux不同,Windows是否明显地对待这两种模式?
fgets()
保持行结尾。
http://msdn.microsoft.com/en-us/library/c37dh6kf(v=vs.80).aspx
fgets()
本身没有用于转换行结尾的任何特殊选项,但在Windows上,您可以选择以“二进制”模式或“文本”模式打开文件。 在文本模式下,Windows将CR / LF序列(C字符串:“\\ r \\ n”)转换为换行符(C字符串:“\\ n”)。 这是一个功能,因此您可以为Windows和Linux编写相同的代码,它可以工作(在Windows上不需要“\\ r \\ n”,在Linux上只需要“\\ n”)。
http://msdn.microsoft.com/en-US/library/yeby3zcb(v=vs.80 )
请注意,对fopen()
的Windows调用采用与在Linux中调用fopen()
相同的参数。 “二进制”模式在文件模式下需要非标准字符( 'b'
),但“文本”模式是默认模式。 所以我建议你只使用相同的Windows和Linux代码行; Windows版本的fopen()
就是为此而设计的。
Linux库的C库没有任何棘手的功能。 如果文本文件具有CR / LF行结尾,那么这就是您在阅读时获得的结果。 Linux fopen()
会在选项中接受'b'
,但忽略它!
在Unix上,这些行将被读取到换行符\\n
并包含回车符\\r
。 你需要将两者都修剪掉。
虽然其他答案给出了令人满意的信息,但是对于在UNIX
下读取的DOS
文件会返回什么样的行结尾这个问题,我想提到另一种方法来切断这样的行结尾。
显着的区别在于,以下方法是多字节字符保存,因为它不直接涉及任何字符:
if (pszLine && (2 <= strlen(pszLine)))
{
size_t size = strcspn(pszLine, "\r\n");
pszLine[size] = 0;
}
你会得到文件中的实际内容,包括\\r
字符。 在unix中没有文本文件和二进制文件,只有文件,而stdio不进行转换。 在使用fgets将行读入缓冲区后,您可以执行以下操作:
char *p = strrchr(buffer, '\r');
if(p && p[1]=='\n' && p[2]=='\0') {
p[0] = '\n';
p[1] = '\0';
}
这会将终止\\r\\n\\0
更改为\\n\\0
。 或者如果你不想保留\\n
你可以做p[0]='\\0'
。
注意使用strrchr,而不是strchr。 没有什么可以阻止多个\\r
出现在一行中间,你可能不希望在第一行中截断该行。
回答问题的编辑部分:是的,“rb”中的“b”是unix中的无操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.