簡體   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