ファイルの最後に新しい行を追加するのはなぜですか?

ファイルの最後に新しい行を追加するのはなぜですか?

一部のコンパイラ(特にCまたはC ++コンパイラ)では、次の警告が表示されます。

No new line at end of file

私はこれがCプログラマーの問題だと思いましたが、githubはコミットビューに次のメッセージを表示します。

\ No newline at end of file

PHPファイルの場合。

プリプロセッサの説明を理解しました。このスレッドしかし、これはPHPとどのような関係がありますか?同じものか、vsテーマに関連していますかinclude()\r\n\n

ファイルの最後に新しい行を追加するのはなぜですか?

答え1

これは、ファイルの末尾に改行を追加するのではなく、そこにある必要がある改行を削除することではありません。

テキストファイルUnixでは、次の一連の要素で構成されています。ワイヤー、それぞれ改行文字\n)。したがって、空ではなく改行文字で終わらないファイルはテキストファイルではありません。

テキストファイルで機能する必要があるユーティリティは、改行文字で終わらないファイルをうまく処理できない可能性があります。たとえば、過去の Unix ユーティリティは、最後の改行文字の後のテキストを無視できます。牛に似た一種の栄養このユーティリティには、他のほとんどの最新のユーティリティと同様に、テキスト以外のファイルとうまく機能するポリシーがありますが、最後の改行文字がないファイルではまだ奇妙な動作が発生する可能性があります。

GNU diffを使用すると、比較されるファイルの1つが改行文字で終わり、他のファイルはそうでない場合に注意してください。 diffは行指向なので、ファイルの1つに改行文字を保存し、他のファイルに改行文字を保存してそれを表すことはできません。改行文字は各行の位置を示す必要があります。diffファイルに始まりと終わり。したがって、diffはこの特殊テキストを使用して、改行\ No newline at end of fileで終わらないファイルと終わるファイルを区別します。

ところで、C コンテキストでは、ソースファイルも一連の行で構成されます。より正確には、翻訳単位は実装時に一連の行として定義され、各行は改行文字(n1256§5.1.1.1)。 UNIXシステムでは、マッピングは簡単です。 DOSとWindowsでは、各CR LFシーケンス(\r\n)は改行文字にマップされます(\nこのオペレーティングシステムがテキストで開いたファイルを読み取るときに常に発生する現象)。一部のオペレーティングシステムには改行文字がありませんが、固定または可変サイズのレコードがあります。これらのシステムでは、ファイルからCソースコードへのマッピングが\n各レコードの最後に導入されます。これはUnixとは直接関係ありませんが、最後の改行文字が欠落しているCソースファイルをレコードベースのテキストファイルを含むシステムにコピーしてから再コピーすると、次のエラーが発生することを意味します。不完全な結果。初期変換中に行が切り捨てられたか、逆方向変換中に改行が追加されました。

1例 :空でないファイルのGNU出力はsort常に改行で終わります。したがって、ファイルに最後の改行文字がない場合、レポートは組み込みの戻りに必要な.needより小さいことがfooわかります。sort foo | wc -ccat foo | wc -creadsh間違った行の終わりに達する前にファイルの終わりに達すると、終了しwhile IFS= read -r line; do ...; doneていない行を完全にスキップするなどのループが発生します。

答え2

必ずしも原因ではありませんが、ファイルが新しい行で終わらない実際の結果は次のとおりです。

を使用するには、次の点を考慮してください。たとえば、3つのファイルの行の先頭で単語を見つけるには、cat次のようにします。foo

cat file1 file2 file3 | grep -e '^foo'

file3 の最初の行が次に始まりますfooが、file2 が最後の行の後に終わらない場合、\ngrep は file2 の最後の行と file3 の最初の行を 1 行として扱うため、この場合は見つかりません。

だから、一貫性を保ち、驚きを避けるために、ファイルは常に新しい行で終わるようにします。

答え3

2つの側面があります。

  1. 一部のCコンパイラは、改行文字で終わらない最後の行を解析できません。 C標準は、Cファイルが改行(C11、5.1.1.2、2.)で終わる必要があり、改行のない最後の行が未定義の動作(C11、J.2、項目2)を生成することを指定します。おそらく歴史的な理由によるものでしょう。最初の標準が作成されたとき、そのようなコンパイラの一部のベンダーは委員会のメンバーでした。したがって、GCCの警告です。

  2. diffプログラム(githubなどで使用されるプログラムgit diff)は、ファイル間の違いを1行ずつ表示します。通常、1つのファイルだけが改行文字で終わる場合はメッセージを印刷します。それ以外の場合、違いを見ることはできません。たとえば、2つのファイル間の唯一の違いがメッセージを表示せずに最後の改行文字があることである場合、2つのファイルは、ファイルの成功とチェックサムと等しくない終了コードを返すときに同じと思われます(diff例:cmpパススルーmd5sum)。しません。

答え4

diff 記録を維持することも重要です。ファイルの末尾に改行文字がない場合、ファイルの最後に追加されたすべての内容は、diffユーティリティで最後の行を変更することで処理されます(追加されて\nいるため)。

git blameこれにより、およびなどのコマンドが不要な結果を生成する可能性がありますhg annotate

関連情報