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


166

一部のコンパイラー(特にCまたはC ++コンパイラー)は、以下に関する警告を表示します。

No new line at end of file

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

\ No newline at end of file

PHPファイルの場合。

私はこのスレッドで説明されているプリプロセッサのことを理解していますが、これはPHPで何をするのでしょうか?同じinclude()ことですか、それとも\r\nvs \nトピックに関連していますか?

ファイルの最後に改行を入れることのポイントは何ですか?



2
人を怒らせる。
アンドリュー

4
catファイルの場合、改行で終わらない場合、次のプロンプトが最後の「行」に追加されます。
アーロンフランケ

回答:


188

ファイルの最後に余分な改行を追加することではなく、そこにあるはずの改行を削除しないことです。

UNIXの下のテキストファイルは一連ので構成され、各行は改行文字\n)で終わります。したがって、空ではなく、改行で終わらないファイルはテキストファイルではありません。

テキストファイルで動作するはずのユーティリティは、改行で終わらないファイルにうまく対応できない場合があります。たとえば、歴史的なUnixユーティリティは、最後の改行の後のテキストを無視する場合があります。GNUユーティリティには、非テキストファイルで適切に動作するポリシーがあり、他のほとんどの最新ユーティリティも同様ですが、最後の改行が欠落しているファイルで奇妙な動作が発生する場合があります¹。

GNU diffでは、比較対象のファイルの1つが改行で終わっていて、もう1つが終わっていない場合、その事実に注意するよう注意してください。diffが行指向であるので、それは他人のためのいずれかのファイルではなく、ために改行を格納することで、これを示すことはできません-改行は場所を示すために必要な各ラインdiffファイルの中に開始および終了。そのため、diffはこの特別なテキスト\ No newline at end of fileを使用して、改行で終わっていないファイルと改行で終わっているファイルを区別します。

ところで、Cコンテキストでは、ソースファイルも同様に一連の行で構成されます。より正確には、変換部は、実装定義の一連のラインとして、改行文字(で終わる必要がありその各々に見たn1256 §5.1.1.1)。UNIXシステムでは、マッピングは簡単です。DOSおよびWindowsでは、各CR LFシーケンス(\r\n)は改行にマッピングされます(\n;これは、これらのOSでテキストとして開かれたファイルを読み取るときに常に発生します)。改行文字を持たず、代わりに固定サイズまたは可変サイズのレコードを持つOSがいくつかあります。これらのシステムでは、ファイルからCソースへのマッピングにより、\n各レコードの最後。これはUNIXには直接関係ありませんが、最終的な改行がないCソースファイルをレコードベースのテキストファイルがあるシステムにコピーし、それをコピーして戻すと、不完全になってしまうことを意味します最初の変換で切り捨てられた最後の行、または逆変換中に余分な改行が追加されます。

¹ 例:GNU sortの出力は常に改行で終わります。そのため、ファイルのfoo最後の改行が欠落している場合、それsort foo | wc -cは1つ以上の文字を報告することがわかりますcat foo | wc -c


「...一連の行は、それぞれ改行文字(n1256§5.1.1.1)で終了する必要があります」に関して->最新のC11dr N1570を再表示したところ、次のようなサポートが見つかりませんでした。 「空ではないソースファイルは改行文字で終わるものとし、そのようなスプライシングが行われる前にバックスラッシュ文字が直前にないものとします。」§5.1.1.22、しかしそれはスプライシング仕様に制限されているようです。
-chux

@chuxその文はn1256にも存在します。最後の行は改行文字で終了する必要があります。最後の行ではない行も、その行が終了して次の行が始まることを示すために、明らかに改行文字で終了する必要があります。したがって、すべての行は改行文字で終了する必要があります。
ジル

うーん、私にとっては、「 "A source file ... splicing takes .."」という行は、一般的なファイルではなく、スプライシングの考慮事項に限定されている可能性があります。
それに

>「diffはこの特別なテキスト\ファイルの終わりに改行なしを使用して、改行で終わっていないファイルと改行で終わっているファイルを区別します。」Gitは、ファイルを比較するときだけでなく、このテキストを表示します。ただし、gitに新しいファイルが追加された場合でも。だから、この議論は無効だと思う。
ヴィクトルクルグリコフ

>「テキストファイルで動作するはずのユーティリティは、改行で終わらないファイルにうまく対応できない可能性があります」要件。gitがこのメッセージを表示する場合、理由はソース管理の問題にあると思います。
ヴィクトルクルグリコフ

41

必ずしも理由ではありませんが、ファイルが改行で終わらないという実際的な結果:

を使用して複数のファイルを処理する場合はどうなるかを検討してくださいcat。たとえば、foo3つのファイルで行の先頭にある単語を検索する場合:

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

file3の最初の行がで始まりfoo、file2の\n最後の行の後にfinal がない場合、file2の最後の行とfile3の最初の行はgrepによって単一として認識されるため、この出現はgrepによって検出されません。ライン。

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


しかし、ファイルの連結を気にするのはgitのビジネスでしょうか?
ヴィクトルクルグリコフ

それはあなただけに置く必要があることを理由に立っていない'\n'...猫の操作で年代を
アンドリュー

3
\n端に空白がある\n _____文字列を一緒に追加することがあるので、一貫性を保つために、常に文字列の両端に配置します。」まあ、いいえ、そこで行う正しいことは、文字列をトリミングしてから、それらを適切に連結することです。
アンドリュー

16

2つの側面があります。

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

  2. diffプログラム(git diff、githubなどで使用される)は、ファイル間の行ごとの違いを示します。通常は、1つのファイルのみが改行で終わる場合にメッセージを出力します。それ以外の場合、この違いは表示されません。同じであった、ときに、2つのファイル間の唯一の違いは、それは両方のファイルのようになりますヒントなしで、最後の改行文字の存在であれば例えばdiff、およびcmp(終了コード不平等な成功とファイルのチェックサムを返すなどを経由してmd5sum)一致しません。


diffプログラムで意味をなす
Thamaraiselvam

diffのような音はもっと賢くなければなりません。
アンドリュー

@アンドリュー、いいえ、そうではありません。diff差異がある場合は出力することが期待されます。そして、あるファイルの最後の文字に改行があり、他のファイルにはない場合、その違いは出力で何らかの形で顕著でなければなりません。
maxschlepzig

後者のステートメントは正しいです。ただし、差分ビューアは「newlines」(\n)を最初に表示する必要はなく、代わりに「new lines」のみを表示できます。
アンドリュー

10

\ No newline at end of fileあなたから取得githubのは(にパッチの最後に表示されるdiff形式で、「統一フォーマット」セクションの最後にある注を参照してください)。

コンパイラーは、ファイルの終わりに改行があるかどうかを気にしませんが、git(およびdiff/ patchユーティリティー)はそれらを考慮する必要があります。それには多くの理由があります。たとえば、ファイルの最後に改行を追加または削除するのを忘れると、ハッシュサム(md5sum/ sha1sum)が変更されます。また、ファイルは常にプログラムであるとは限らず、ファイナル\nは何らかの違いをもたらす可能性があります。

:Cコンパイラからの警告については、下位互換性のために最終的な改行を要求していると思います。非常に古いコンパイラは、\n(または他のシステム依存の行末文字シーケンス)で終わらない場合、最終行を受け入れない場合があります。


7
「下位互換性のために、最終的な改行を要求していると思います」 -いいえ、C標準で義務付けられているため、彼らはそれを主張しています。
メストレリオン

1
@MestreLion Cでは、Cソースコードの最終改行が必要です(C11§5.1.1.22)。テキストファイルI / Oの場合、Cには「最後の行で改行文字の終了が必要かどうかは実装定義です」ということに注意してください。§7.21.22
chux

非常に古いコンパイラを使用しているのは誰ですか?それらの使用を停止します。
アンドリュー

1
@MestreLion:そして、なぜあなたはCの標準的な義務にそれを思い...
ステファン・ヒメネス

@StéphaneGimenez:異なるOS間の一貫性、優れた互換性、相互運用性(POSIXは '\ n'で終わる行も定義します)
MestreLion

4

POSIX。これは、オペレーティングシステム間の互換性を維持するためにIEEEが指定した一連の標準です。

その1つは、「行」の定義であり、ゼロ個以上の非文字と終了改行文字のシーケンスです。

したがって、その最後の行が実際の「行」として認識されるためには、改行文字で終了する必要があります。

これは、OSのツールに依存して行カウントやファイルの解析/分割を支援する場合に重要です。PHPはスクリプト言語であるため、特に初期または現在でも(可能性はありませんが)、OSに依存していました。

実際には、ほとんどのオペレーティングシステムはPOSIXに完全に準拠しておらず、人間はそのようなマシンではなく、新しいラインの終端を気にしません。だから、ほとんどの場合、それはそれを気遣う、警告する、または単に最後のテキストを行かせるすべてのもののバイキングですので、それを含めてください。


3

また、差分履歴を保持するポイントもあります。ファイルが改行文字なしで終了する場合、ファイルの最後に何かを追加すると、diffユーティリティはその最後の行を変更するものとして表示されます(\n追加されるため)。

これにより、git blameやなどのコマンドで望ましくない結果が生じる可能性がありますhg annotate


差分のように聞こえるのは、もっと賢くする必要があるだけです。
アンドリュー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.