剪断が乱れているrnとnを徹底的に解読し、WindowsとLinuxを例に


多くのプログラマーは、次の2つの問題に何気なく遭遇します.
        1. linuxにvimで書かれたファイルtest.txtをwindowsにコピーすると、すべての内容が1行に表示されます.(もちろん、Windowsの編集ディスプレイがスマートであれば、それは別です)
        2. Windowsで作成されたtest.txtをlinuxにコピーすると、linuxプログラムが異常に実行されます.(もちろん、linuxプログラムが十分丈夫であれば問題ありません)
ps.Windowsにlinux shell scriptを書き、linuxにコピーして実行すると、問題が発生します.
なぜ上記の問題が発生したのでしょうか.これは私たちがrとを理解する必要があります.
まずWindowsを例に説明します.新しいdosを作ろうtxtファイルを最初の行でenterキーを押してファイルを保存します.このとき、このファイルのサイズを調べてみると、2バイト(1個ではなく)であることがわかり、UltraEditで調べてみると、ファイルの2バイトが0 x 0 dと0 x 0 a、つまりrとなる.ただし、Cプログラムでdosを読み取ると.txtファイル、またまったくrまで読み取っていないことに気づいて、これはどういうことですか?Windows上のdos.txtファイルでenterキーを押すと、実際にはCプログラムの文字を書くことに相当しますが、歴史的な理由でファイルを書くとき、Windowsシステムは自動的に前にrを付けます.これでdos.txtファイルの中にrが入っていて、読み取る時、Windowsシステムは自動的にrを取り除くことができて、だからあなたのCプログラムはまったくrを読むことができなくて、やはり.
正直に言うと、私は多くの場所でr和を話していることに気づきました.よく言えません.次はもっとはっきりしていることを望んでいます.もっとはっきりしているのではなく、もっとはっきりしています.
Windowsシステムには次のような等価関係があります.
enter改行<=======>>プログラム書き込み<======>>本格的にファイルにr(0 x 00 d 0 x 0 a)<======>>プログラムが本格的に読み込んだのは
linuxシステムでの等価関係:
enterで改行<=======>>プログラム書き込み<======>>本当にファイルに書き込み(0 x 0 a)<=====>>プログラムが本当に読み込んだのは
では、本稿の冒頭の問題を見てみましょう.linuxの下にunixがあると仮定します.txtファイル、では、ファイル内の改行フラグは、unix.txtコピーはWindowsに頼っています.それはいいですね.Windowsの鋭い目つきはunixに向かっているようです.txtファイルは言います:私と何もしないでください、私はファイルの中のrだけを知っていて、もしあなたのこのunix.txtファイルにrが入っているので、改行文字だと思います.そうしないと、私はあなたを認識しません.これでWindowsにはunixが見つからない.txtの中のrなので、Windowsにとってはunixはまったく発見されない.txtには改行があるので、Windowsから見たunixです.txtファイルは1行に表示されます.
同じように、Windowsにdosがあると仮定します.txtファイル、では、ファイルの改行フラグはrで、今linuxの下にコピーして、それはいいですね.linusのように、linuxという強情なやつは「ほかの私は気にしないで、ファイルの中に出会ったら、改行だと思っています.他の人は、普通の文字だと思っています」と言っているようです.これにより、rはファイルの正常な部分として扱われます.つまり、linuxの下のCプログラムは読み取るだけでなく、前のrにも読み出されます.
実際にWindows上のファイルはdos形式ですが、linux上のファイルはunix形式です.linux上のdos 2 unixとunix 2 dosで変換できます.もちろん、busybox環境ではbusybox dos 2 unixとbusybox unix 2 dosが必要です.
次に、上記の部分の説明をプログラムで簡単に検証します.Windowsにdosを作成します.txtファイルは、1行目が12に書き込まれ、enterを押し、2行目が3に書き込まれ、enterを押さずに保存されます.まずWindowsのプログラムを見てみましょう.
// VC++6.0

#include 
#include 

int main()
{
	char szTest[100] = {0};
	int len = 0;

	FILE *fp = fopen("dos.txt", "r");
	if(NULL == fp)
	{
		printf("failed to open dos.txt
"); return 1; } fgets(szTest, sizeof(szTest) - 1, fp); len = strlen(szTest); if('
' == szTest[len - 1]) { printf("yes1
"); } if('\r' == szTest[len - 2]) { printf("yes2
"); } memset(szTest, 0, sizeof(szTest)); fgets(szTest, sizeof(szTest) - 1, fp); len = strlen(szTest); if('
' == szTest[len - 1]) { printf("yes3
"); } if('\r' == szTest[len - 2]) { printf("yes4
"); } fclose(fp); return 0; }

プログラムの結果:
yes1
私たちは、読み取ったときにrが確かに取り除かれたのを見ました.
はい、dos.txtをlinuxにコピーし、次の同じプログラムを実行します.
// gcc

#include 
#include 

int main()
{
	char szTest[100] = {0};
	int len = 0;

	FILE *fp = fopen("dos.txt", "r");
	if(NULL == fp)
	{
		printf("failed to open dos.txt
"); return 1; } fgets(szTest, sizeof(szTest) - 1, fp); len = strlen(szTest); if('
' == szTest[len - 1]) { printf("yes1
"); } if('\r' == szTest[len - 2]) { printf("yes2
"); } memset(szTest, 0, sizeof(szTest)); fgets(szTest, sizeof(szTest) - 1, fp); len = strlen(szTest); if('
' == szTest[len - 1]) { printf("yes3
"); } if('\r' == szTest[len - 2]) { printf("yes4
"); } fclose(fp); return 0; }

結果:
[taoge@localhost learn_c]$ xxd dos.txt 
0000000: 3132 0d0a 33                             12..3
[taoge@localhost learn_c]$ gcc test.c 
[taoge@localhost learn_c]$ ./a.out 
yes1
yes2
[taoge@localhost learn_c]$ 
私たちが見たのは、読み取ったとき、rはまだいました.
OK、これで、r和の問題は基本的に明らかになったので、これからは葛藤する必要はありません.