[英]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.