我有一个在运行时收到的带有DOS行结尾的文件,因此我无法将行结尾转换为UNIX样式离线。此外,我的应用程序在Windows和Linux上运行。我的应用程序对文件执行fgets()
并尝试逐行读取。
Linux上每行读取的字节数也会占用2个尾随字符(\r \n)
,还是只包含(\ n)和 \ r 将被底层系统丢弃?
编辑:
好的,所以在Linux上读取文件时会保留行结尾,但我遇到了另一个问题。在Windows上,以“r”或“rb”打开文件的行为有所不同。与Linux不同,Windows是否明确地处理这两种模式?
答案 0 :(得分:4)
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()
专为此而设计。
C库的Linux版本没有任何棘手的功能。如果文本文件具有CR / LF行结尾,那么这就是您在阅读时获得的结果。 Linux fopen()
会在选项中接受'b'
,但会忽略它!
答案 1 :(得分:3)
在Unix上,这些行将被读取到换行符\n
并包含回车符\r
。你需要在最后修剪它们。
答案 2 :(得分:1)
虽然其他答案给出了令人满意的信息,但是对于在DOS
下阅读的UNIX
文件会返回什么样的行结尾的问题,我想提到另一种方法来切断这样的行尾。
显着的区别在于,以下方法是多字节字符保存,因为它不直接涉及任何字符:
if (pszLine && (2 <= strlen(pszLine)))
{
size_t size = strcspn(pszLine, "\r\n");
pszLine[size] = 0;
}
答案 3 :(得分: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
。或者,如果您不想保留p[0]='\0'
,则可以\n
。
注意使用strrchr,而不是strchr。没有什么可以防止多个\r
出现在一行中间,你可能不想截断第一行一行。
回答问题的 EDIT 部分:是的,“rb”中的“b”是unix中的无操作。