2015-06-26 69 views
6

這個想法來自關於實際問題Replacing multiple new lines in a file with just one的討論。使用在Windows 8.1機器上運行的cygwin終端時發生錯誤。如果(c ==' n')處理跨平臺文件,是否需要編寫「portable」?

末以來的行終止會有所不同,像\n\r,或\r\n,是否需要寫一個「便攜式」 if(c=='\n'),使其在Linux,Windows和OS X很好地工作?或者,最佳實踐只是用命令/工具轉換文件?

#include <stdio.h> 
    int main() 
    { 
     FILE * pFile; 
     int c; 
     int n = 0; 
     pFile=fopen ("myfile.txt","r"); 
     if (pFile==NULL) perror ("Error opening file"); 
     else 
     { 
     do { 
      c = fgetc (pFile); 
      if (c == '\n') n++; // will it work fine under different platform? 
     } while (c != EOF); 
     fclose (pFile); 
     printf ("The file contains %d lines.\n",n); 
     } 
     return 0; 
    } 

UPDATE1:

CRT總是轉換行結尾爲 '\ n'?

+1

CRT將始終將行結束符轉換爲''\ n'',因此如果您將文件作爲文本讀取,它將自動移植。除非你想從任何類型的行尾讀取任何平臺的文件 –

+0

@LưuVĩnhPhúc謝謝。如果試圖在Linux下讀取一個文件(在windows上創建),最好的做法是重寫'if(c =='\ n')',或者只是用命令/工具轉換文件? –

+0

@LưuVĩnhPhúc錯誤(一般)。如果文件/流以「ASCII模式」(僅在Microsoft平臺上存在*)打開,則行結束僅在Microsoft平臺上進行翻譯 – joop

回答

4

如果以二進制模式打開輸入文件(模式字符串中的字符'b'),那麼有必要擔心在'\n'之前可能存在'\r'

如果文件未在二進制模式打開(並且還沒有讀使用二進制功能,諸如fread()),那麼沒有必要'\n'之前擔心的'\r'存在,因爲通過接收到的輸入之前,將被處理您的代碼 - 通過相關的系統功能(例如從磁盤讀取輸入的設備驅動程序或從stdin)或通過執行用於從文件讀取輸入的功能。

如果您正在系統間傳輸文件(例如,在linux下編寫文件,並將其傳輸到Windows系統,程序試圖讀取它),那麼您可以選擇;

  • 讀寫的非二進制模式的文件,並在系統間傳輸時,做文件的相關的翻譯。如果使用ftp,可以通過使用文本模式而不是二進制模式來傳輸文件。如果文件以二進制模式傳輸,則需要通過dos2unix(如果將文件傳輸到unix)或通過unix2dos(以其他方式)運行文件。
  • 以二進制模式執行所有I/O,使用二進制模式在系統之間傳輸它們,並且從不以非二進制模式讀取它們。除此之外,這使您可以明確控制文件中的數據。
  • 以文本模式編寫文件,按照您認爲合適的方式傳輸文件。然後只能以二進制模式讀取,並且當您的讀取代碼遇到\r\n對時,請刪除'\r'字符。

最後可以說是最強大的 - 寫代碼可能包括\r\n字符,也可能沒有,但識別代碼簡單地忽略它一個'\n'字符之前遇到的任何'\r'字符。如果手動編輯這些文件(例如,使用文本編輯器 - 可能被單獨配置爲插入或刪除\r\n),則這些代碼甚至可能會應對。

+0

+1這些是選項。我會去完全控制二元轉移:工作量是相同的,但涉及的因素較少 – slezica

+0

也許是這樣。但是OP沒有提供足夠的信息來幫助選擇不同的選項。 – Peter

+0

@Peter感謝您的詳細分析。它確實有幫助。 –