剪断が乱れているrnとnを徹底的に解読し、WindowsとLinuxを例に
4046 ワード
多くのプログラマーは、次の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のプログラムを見てみましょう.
プログラムの結果:
yes1
私たちは、読み取ったときにrが確かに取り除かれたのを見ました.
はい、dos.txtをlinuxにコピーし、次の同じプログラムを実行します.
結果:
[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和の問題は基本的に明らかになったので、これからは葛藤する必要はありません.
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和の問題は基本的に明らかになったので、これからは葛藤する必要はありません.