繁体   English   中英

使用Linux上的fgets()读取DOS行结尾的文件

[英]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' ,但忽略它!

http://linux.die.net/man/3/fopen

http://linux.die.net/man/3/fgets

在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM