1. 程式人生 > 實用技巧 >windows下操作檔案換行符的問題

windows下操作檔案換行符的問題

回車換行符的歷史背景:

早期的計算機輸出裝置不是顯示器,而是電傳打字機,結構與普通的打字機差不多。有一個列印頭在紙上打字,同時有一個電動機控制紙張的進出。當列印頭到達行尾的時候,需要兩個動作才能夠到達下一行的行首:

1: 首先執行回車動作,將列印頭移動到本行的行首;

2: 然後進行換行動作,電動機將紙張向上移動一行,這樣列印頭就處於下一行的行首,可以繼續進行列印。

回車和換行對應的控制字元分別是\r和\n,這就是windows中換行符為\r\n的由來。

後來由於經常連續執行,所以在印表機中將這兩個控制字元簡化為一個控制字元,這就是linux/unix中的換行符\n的由來。

不同作業系統換行符的區別
:

Unix系統中:  每行結尾只有"<換行>",即"\n";

         對應十六進位制0x0A

Windows系統中:每行結尾是"<回車><換行>",即"\r\n";

        對應十六進位制0x0D 0x0A

Mac系統中:  每行結尾是"<回車>",即"\r"。

        對應十六進位制0x0D

由於換行符不同,導致的結果是:

  Unix/Mac系統下的檔案在Windows裡開啟的話,所有文字會變成一行;

  而Windows裡的檔案在Unix/Mac下開啟的話,在每行的結尾可能會多出一個^M符號.

而在windows下操作檔案fopen使用”r”和”rb”開啟檔案,結果是不一樣的(Linux下沒有區別):

  如果fopen是”r”文字方式開啟,讀檔案時會自動轉換換物符\r\n為\n。

  如果fopen是”r”文字方式開啟,寫檔案時會自動轉換換物符\n為\r\n。

  如果fopen是”rb”是以二進位制方式開啟,不會自動轉換。

環境實驗:windows fopen rrb的區別

在windows環境和Linux環境下,分別建立一個文字,內容相同:

  Hello World!

  5AA555AA

windows下建立的檔案,命名為windows.txt

Linux下建立的檔案,命名為Linux.txt

寫個程式將使用fopen( path, “rb”)文本里面的內容讀出來:

 1 #include <stdio.h>
 2 
 3  
 4 
 5 int main( int argc, char ** argv ){
 6 
 7   FILE *fp;
 8 
 9   char buf[255] = { 0 };
10 
11   size_t num = 0;
12 
13   int i = 0;
14 
15  
16 
17 if( argc != 2 ){
18 
19   printf( "You need to input the file to read!" );
20 
21 return -1;
22 
23 }
24 
25  
26 
27 if((fp = fopen( argv[1], "rb" )) == NULL )
28 
29   printf( "file open failed!" );
30 
31  
32 
33 while( (num = fread(buf, sizeof(char), 10, fp )) > 0 ){
34 
35   for( i = 0; i < num; ++i ){
36 
37     printf( "%02X", buf[i] );
38 
39   }
40 
41 }
42 
43  
44 
45 fclose( fp );
46 
47 return 0;
48 
49  
50 
51 }

fopen( path, rb) 輸出結果為:

結果windows下建立的文字換行符仍然是 0D0A(即\r\n),Linux下建立的檔案為 0A(\n)

將上述程式碼改為 fopen( path, r)

輸出結果如下:

如上, 換行符統一被轉換為0A(即\n

注意:如果Linux建立的文字,在windows下有編輯過,檔案裡面的0A會被轉換為0D0A

比如我複製一份Linux.txt為Linux1.txt,在windows下用記事板開啟檔案,顯示檔案為:

按CTRL+S儲存後,0A被轉換為0D0A:

檔案格式轉換:

那如果我們有檔案需要在不同的作業系統中來回切換操作, 怎麼處理文件內的換行符呢?

方法1NotePad++ 轉換

設定行尾符格式:編輯-> 檔案格式轉換->(可選Windows、Unix和Mac中的一種)(如果是英文版的Notepad++,則應該是Edit -> EOL Conversion -> Windows Format、Unix/OSX Format、Old Mac Format。)

方法2 使用UNIX命令轉換:

  unix2dos -k xxx_file

  dos2unix -k xxx_file