windows下操作文件換行符的問題


 為什么寫這篇文章?

    因為在工作過程中, 經常會切換Linux 和Windows, 操作文檔時有兩次遇到莫名的問題, 怎么查程序都查不出來, 因為邏輯都沒問題,但是數據就是出錯了。查了N天,發現是不同操作系統換行符的問題,搞得血都吐了一堆。而網上很多文章感覺都沒有講的很清晰。

 為了不讓大家重蹈覆轍,參考了其他網站的文章,特地總結了一下, 希望能在一篇文章里把問題講解清楚。

    當然,如果其中理解有誤的地方,請各位提出來。本來想分析一下源碼,但是沒有找到相關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 r rb的區別

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

  Hello World!

  5AA555AA

windows下創建的文件,命名為windows.txt

Linux下創建的文件,命名為Linux.txt

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

 
         

#include <stdio.h>

 

int main( int argc, char ** argv ){

 
         

  FILE *fp;

  char buf[255] = { 0 };

  size_t num = 0;

  int i = 0;

 

  if( argc != 2 ){

  printf( "You need to input the file to read!" );
  return -1;
}

 if((fp = fopen( argv[1], "rb" )) == NULL )
   printf( "file open failed!" );

  while( (num = fread(buf, sizeof(char), 10, fp )) > 0 ){

    for( i = 0; i < num; ++i ){

      printf( "%02X", buf[i] );

    }

  }

  fclose( fp );

  return 0;

}

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

 

參考文章: 1: https://blog.csdn.net/wzb56_earl/article/details/6860358

      2:https://www.cnblogs.com/cnjavahome/p/8893813.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM