C#の改行コード完全ガイド|文字列・Console・環境別の正しい使い方

はじめに

C#で文字列やファイル、コンソール出力を扱っていると、「改行したいだけなのに表示が崩れる」「\nを書いたのに改行されない」「Windowsでは問題ないのにLinuxで動きが違う」といった問題に出会うことがあります。

C#の改行は、単に「改行したいなら\n」と覚えるだけでは不十分です。文字列内で使うのか、Consoleに出力するのか、ファイルへ書き込むのか、Web画面に表示するのかによって、正しい書き方が変わります。

この記事では、C#の改行コードについて、\n\r\n\rEnvironment.NewLineの違いから、文字列・Console・ファイル・UI・Webでの実践的な使い分けまで、初心者にもわかりやすく解説します。

1. C#の改行コードとは?まず押さえる基本

1-1. 改行コードとは何か

改行コードとは、文字列やテキストファイルの中で「ここで行を変える」という意味を持つ特殊な文字です。

たとえば、画面上では次のように2行に見える文章があるとします。

こんにちは
C#を学習中です

内部的には、1行目と2行目の間に改行コードが入っています。

こんにちは\nC#を学習中です

C#では、改行コードを文字列の中に直接書くために、主にエスケープシーケンスを使います。代表的なのが\n\r\nです。

1-2. C#で使う主な改行コードの種類

C#でよく使う改行コードは、次の4つです。

書き方名称主な意味
\nLF / Line Feed次の行へ進む
\r\nCRLFWindowsでよく使われる改行
\rCR / Carriage Return行頭へ戻る
Environment.NewLine環境依存の改行文字列実行環境に合わせた改行

C#の文字列リテラルでは、\nは新しい行、\rはキャリッジリターンを表すエスケープシーケンスとして扱われます。MicrosoftのC#文字列リテラルの説明でも、\nは新しい行、\rはキャリッジリターンとして定義されています。

1-3. \n・\r\n・\rの違い

\n\r\n\rは、どれも改行に関係しますが、意味は同じではありません。

\nはLine Feedの略で、次の行へ進むことを表します。LinuxやmacOSのテキストファイルでは、基本的に\nが改行として使われます。

C#
string text = "1行目\n2行目";
Console.WriteLine(text);

出力結果は次のようになります。

1行目
2行目

\r\nは、Carriage ReturnとLine Feedを組み合わせた改行コードです。Windowsのテキストファイルでは、伝統的に\r\nが改行として使われます。

C#
string text = "1行目\r\n2行目";
Console.WriteLine(text);

\rはCarriage Returnの略で、もともとはカーソルや印字位置を行頭に戻す意味を持ちます。現在のC#アプリケーションで単独の\rを改行目的で使う場面は多くありません。古いMac OS系のテキストなどを扱う場合に見かけることがあります。

1-4. Windows・Linux・macOSで改行コードが異なる理由

OSによって改行コードが異なるのは、歴史的な経緯によるものです。

Windowsでは、改行に\r\nが使われることが多く、Linuxや現在のmacOSでは\nが使われることが一般的です。古いMac OSでは\rが使われていました。

そのため、Windowsで作成したテキストファイルをLinuxで扱ったり、Linux上で生成したファイルをWindowsの古いツールで開いたりすると、改行が期待どおりに表示されないことがあります。

現在の多くのエディタやIDEは複数の改行コードに対応していますが、バッチ処理、ログ解析、CSV出力、Git管理、Docker環境などでは、改行コードの違いがトラブルの原因になることがあります。

1-5. C#で改行を扱うときの基本方針

C#で改行を扱うときは、次の方針で考えると迷いにくくなります。

目的おすすめ
手軽に文字列内で改行したい\n
Windows向けのテキストを明示的に作りたい\r\n
実行環境に合わせたいEnvironment.NewLine
Consoleに1行ずつ出力したいConsole.WriteLine
複数行を効率よく組み立てたいStringBuilder.AppendLine
Web画面で改行表示したい<br>やCSSを使う

重要なのは、「どこで使う改行なのか」を意識することです。C#内部の文字列、OS上のファイル、コンソール、HTML、JSONでは、改行の扱い方が少しずつ異なります。

2. C#で文字列に改行を入れる方法

2-1. \nを使って文字列内で改行する

C#で最も簡単に文字列内へ改行を入れる方法は、\nを使うことです。

C#
string message = "おはようございます。\n今日もよろしくお願いします。";

Console.WriteLine(message);

出力結果は次のようになります。

おはようございます。
今日もよろしくお願いします。

\nは短く書けるため、コード例、ログメッセージ、簡単な出力ではよく使われます。

C#
string profile = "名前: 山田太郎\n年齢: 30\n職業: エンジニア";
Console.WriteLine(profile);

ただし、Windows形式のテキストファイルとして厳密に出力したい場合は、\nではなく\r\nEnvironment.NewLineを検討します。

2-2. \r\nを使ってWindows向けに改行する

Windows向けのテキストファイルや、CRLFを要求する仕様のデータを作る場合は、\r\nを使います。

C#
string text = "1行目\r\n2行目\r\n3行目";
Console.WriteLine(text);

たとえば、古いWindowsアプリケーションや一部の外部システムに渡すテキストでは、改行コードとしてCRLFが前提になっていることがあります。

C#
string windowsText = "Header\r\nBody\r\nFooter";

ただし、すべてのC#コードで常に\r\nを使えばよいわけではありません。LinuxコンテナやmacOS上で動くアプリケーションでは、環境に合わない改行コードになる場合があります。

2-3. Environment.NewLineを使って環境に合わせる

OSや実行環境に合わせた改行を使いたい場合は、Environment.NewLineを使います。

C#
string text = "1行目" + Environment.NewLine + "2行目";
Console.WriteLine(text);

Environment.NewLineは、現在のプラットフォームに合わせた改行文字列を返します。また、Console.WriteLineStringBuilder.AppendLineでは、この改行が自動的に追加されます。

Windows上では通常\r\n、Unix系環境では通常\nになります。そのため、実行環境に自然に合わせたいアプリケーションでは、Environment.NewLineが便利です。

2-4. 文字列連結で改行を入れる

文字列連結で改行を入れることもできます。

C#
string message =
"処理を開始しました。" + Environment.NewLine +
"データを読み込みました。" + Environment.NewLine +
"処理が完了しました。";

Console.WriteLine(message);

短い文字列であれば問題ありませんが、行数が多い場合はコードが読みづらくなります。

C#
string message = "A\n" + "B\n" + "C\n";

このような場合は、StringBuilderstring.Joinを使ったほうが可読性が高くなります。

2-5. 文字列補間で改行を含める

変数の値を埋め込みながら改行したい場合は、文字列補間を使うと便利です。

C#
string name = "佐藤";
int score = 85;

string result = $"名前: {name}\n点数: {score}点";

Console.WriteLine(result);

出力結果は次のとおりです。

名前: 佐藤
点数: 85点

Environment.NewLineと組み合わせることもできます。

C#
string result = $"名前: {name}{Environment.NewLine}点数: {score}点";

OSに合わせた改行にしたい場合は、文字列補間の中でもEnvironment.NewLineを使うとよいでしょう。

2-6. 逐語的文字列リテラルで複数行文字列を書く

C#では、@を付けた逐語的文字列リテラルを使うと、複数行の文字列をそのまま書けます。

C#
string message = @"1行目
2行目
3行目";

Console.WriteLine(message);

逐語的文字列リテラルでは、ソースコード上の改行が文字列の一部として保持されます。Microsoftの説明でも、逐語的文字列は複数行の文字列やバックスラッシュを含む文字列に便利で、改行文字が文字列テキストの一部として保持されるとされています。

ファイルパスを書くときにも便利です。

C#
string path = @"C:\Users\Sample\Documents";

ただし、複数行文字列として使う場合は、ソースコード上のインデントや空白も文字列に含まれる点に注意が必要です。

2-7. raw string literalで複数行文字列を書く

C# 11以降では、raw string literalを使って複数行文字列をより読みやすく書けます。

C#
string json = """
{
"name": "Taro",
"message": "Hello"
}
""";

Console.WriteLine(json);

raw string literalは、少なくとも3つのダブルクォートで開始・終了します。複数行のJSON、SQL、HTML、正規表現など、エスケープが多くなりがちな文字列を書くときに便利です。Microsoftのドキュメントでも、生の文字列リテラルは複数行の文字列を簡単に作成でき、エスケープシーケンスを必要とする文字も扱いやすいと説明されています。

たとえば、メール本文のテンプレートも見やすく書けます。

C#
string mailBody = """
山田様

いつもお世話になっております。
以下の内容をご確認ください。

よろしくお願いいたします。
""";

raw string literalは、複数行テキストをソースコード上で自然に表現したい場合に非常に便利です。

3. Consoleで改行する方法

3-1. Console.WriteLineで自動的に改行する

C#のコンソール出力で改行したい場合、最も基本的なのはConsole.WriteLineです。

C#
Console.WriteLine("1行目");
Console.WriteLine("2行目");
Console.WriteLine("3行目");

出力結果は次のようになります。

1行目
2行目
3行目

Console.WriteLineは、指定した文字列を出力したあと、自動的に改行を追加します。自分で\nEnvironment.NewLineを追加しなくても、1回の呼び出しごとに行が変わります。

3-2. Console.Writeで明示的に改行コードを入れる

Console.Writeは、文字列を出力しても自動では改行しません。

C#
Console.Write("Hello");
Console.Write("World");

出力結果は次のようになります。

HelloWorld

改行したい場合は、明示的に改行コードを入れます。

C#
Console.Write("Hello\n");
Console.Write("World");

または、Environment.NewLineを使います。

C#
Console.Write("Hello" + Environment.NewLine);
Console.Write("World");

Console.Writeは、同じ行に文字を続けて出したい場合や、進捗表示のように細かく制御したい場合に向いています。

3-3. Console.WriteLineとEnvironment.NewLineの使い分け

コンソールに1行ずつ表示したいだけなら、基本的にはConsole.WriteLineを使えば十分です。

C#
Console.WriteLine("処理開始");
Console.WriteLine("処理中");
Console.WriteLine("処理完了");

一方、1つの文字列の中に複数行のメッセージを作りたい場合は、Environment.NewLineを使うと自然です。

C#
string message =
"処理開始" + Environment.NewLine +
"処理中" + Environment.NewLine +
"処理完了";

Console.WriteLine(message);

注意したいのは、すでに改行を含む文字列をConsole.WriteLineで出力すると、最後にも改行が追加されることです。

C#
Console.WriteLine("1行目\n2行目\n");

この場合、末尾の\nに加えてWriteLineの改行も入るため、余分な空行が出ることがあります。

3-4. コンソール出力で改行されないときの確認ポイント

Consoleで改行されない場合は、次の点を確認します。

まず、Console.Writeを使っていないか確認してください。Console.Writeは自動改行しません。

C#
Console.Write("1行目");
Console.Write("2行目");

次に、\nを通常の文字として書いていないか確認します。

C#
Console.WriteLine(@"1行目\n2行目");

このコードでは、逐語的文字列リテラルを使っているため、\nは改行ではなく、バックスラッシュとnの2文字として扱われます。

改行したい場合は、通常の文字列リテラルにします。

C#
Console.WriteLine("1行目\n2行目");

また、ログビューア、IDEの出力ウィンドウ、外部ツールによっては、改行の表示方法が異なる場合があります。コンソールでは改行されていても、別の表示先では見え方が変わることがあります。

3-5. 改行を含むメッセージを見やすく出力する例

複数行のメッセージを見やすく出力するなら、次のように書くとわかりやすくなります。

C#
string userName = "田中";
int count = 5;

string message =
$"ユーザー名: {userName}" + Environment.NewLine +
$"処理件数: {count}" + Environment.NewLine +
"ステータス: 完了";

Console.WriteLine(message);

出力結果は次のとおりです。

ユーザー名: 田中
処理件数: 5
ステータス: 完了

行数が増える場合は、StringBuilderを使う方法もおすすめです。

C#
var sb = new StringBuilder();

sb.AppendLine("処理結果");
sb.AppendLine("--------");
sb.AppendLine($"ユーザー名: {userName}");
sb.AppendLine($"処理件数: {count}");
sb.AppendLine("ステータス: 完了");

Console.WriteLine(sb.ToString());

4. Environment.NewLineの正しい使い方

4-1. Environment.NewLineとは何か

Environment.NewLineは、現在の実行環境に合った改行文字列を返すプロパティです。

C#
string newLine = Environment.NewLine;

C#でOSに依存しない改行を書きたいときによく使われます。

C#
string text = "A" + Environment.NewLine + "B";

Windows、Linux、macOSなど、アプリケーションが動作する環境に応じて適切な改行文字列を使いたい場合に便利です。

4-2. Environment.NewLineが返す値

Environment.NewLineが返す値は、実行環境によって変わります。

代表的には次のようになります。

実行環境Environment.NewLine
Windows\r\n
Linux\n
macOS\n

Microsoftのドキュメントでは、Environment.NewLineの値は現在のプラットフォームと実装に合わせてカスタマイズされた定数とされています。

確認するには、次のようなコードを書けます。

C#
Console.WriteLine(Environment.NewLine == "\r\n");
Console.WriteLine(Environment.NewLine == "\n");

ただし、Environment.NewLine自体は目に見えない文字列なので、内容を直接表示してもわかりにくい点に注意しましょう。

4-3. \nではなくEnvironment.NewLineを使うべきケース

Environment.NewLineを使うべきなのは、実行環境に合わせた自然な改行にしたい場合です。

たとえば、次のようなケースです。

ケース理由
OSに合わせてテキストファイルを出力するWindowsではCRLF、LinuxではLFにしたい
コンソール向けの複数行メッセージを作る環境に合わせた表示にできる
デスクトップアプリでユーザー向けメッセージを作る実行環境に自然な改行になる
ローカルログを出力するOS標準の改行に合わせやすい

例は次のとおりです。

C#
string report =
"売上レポート" + Environment.NewLine +
"日付: 2026-06-06" + Environment.NewLine +
"合計: 100000円";

アプリケーションがWindowsだけでなくLinuxやmacOSでも動く場合は、Environment.NewLineを使うと安全です。

4-4. Environment.NewLineを使わないほうがよいケース

一方で、常にEnvironment.NewLineを使えばよいわけではありません。

次のように、仕様として改行コードが決まっている場合は、その仕様に従うべきです。

ケース推奨
HTTPヘッダーなどCRLFが決まっている形式\r\n
JSON内で改行エスケープを表現したい\n
Git管理でLFに統一している設定ファイル\n
外部APIがLFを要求する\n
CSV仕様や連携先がCRLFを要求する\r\n

たとえば、外部システムが「改行はLFで送ってください」と指定しているなら、Windows上で動くC#アプリでもEnvironment.NewLineではなく\nを使うべきです。

C#
string payload = string.Join("\n", lines);

「環境に合わせる」のか「仕様に合わせる」のかを区別することが重要です。

4-5. .NET Framework・.NET・Unityでの注意点

.NET Framework、現在の.NET、UnityなどでC#を書く場合も、基本的な考え方は同じです。ただし、実行環境によってEnvironment.NewLineの値や、表示先の挙動が変わることがあります。

Windows専用の.NET Frameworkアプリでは、通常はWindowsの改行であるCRLFを前提にして問題ない場面が多いです。

一方、現在の.NETはクロスプラットフォームで動作するため、Windows、Linux、macOSで同じコードが動くことがあります。この場合は、ファイル出力やログ出力で改行コードの違いを意識する必要があります。

Unityでは、エディタ上、Windowsビルド、macOSビルド、モバイル環境など、動作環境が変わることがあります。UI表示ではEnvironment.NewLineよりも、TextコンポーネントやTextMeshPro側の改行解釈を確認することが大切です。

4-6. クロスプラットフォーム開発での実践的な使い分け

クロスプラットフォーム開発では、次のように使い分けると安全です。

アプリ内部のメッセージやOSに自然なログには、Environment.NewLineを使います。

C#
string log = "Start" + Environment.NewLine + "End";

仕様でLFが決まっている設定ファイルやデータには、\nを使います。

C#
string config = string.Join("\n", configLines);

Windowsアプリや外部システムがCRLFを要求する場合は、\r\nを使います。

C#
string windowsFile = string.Join("\r\n", lines);

つまり、改行コードは「C#として正しいか」ではなく、「出力先や仕様に合っているか」で選ぶのが正解です。

5. ファイル出力・読み込みで改行コードを扱う方法

5-1. StreamWriter.WriteLineで改行して書き込む

テキストファイルへ1行ずつ書き込みたい場合は、StreamWriter.WriteLineを使います。

C#
using var writer = new StreamWriter("sample.txt");

writer.WriteLine("1行目");
writer.WriteLine("2行目");
writer.WriteLine("3行目");

WriteLineを使うと、各行の末尾に改行が追加されます。明示的に\nを付ける必要はありません。

C#
writer.WriteLine("ログ開始");
writer.WriteLine("処理中");
writer.WriteLine("ログ終了");

逆に、すでに改行を含む文字列をWriteLineで書くと、余分な改行が入る場合があります。

C#
writer.WriteLine("1行目\n2行目\n");

このような場合は、末尾の改行を取り除くか、Writeを使って自分で制御します。

5-2. File.WriteAllLinesで複数行を書き込む

配列やリストの各要素を1行ずつファイルへ書き込みたい場合は、File.WriteAllLinesが便利です。

C#
string[] lines =
{
"1行目",
"2行目",
"3行目"
};

File.WriteAllLines("sample.txt", lines);

File.WriteAllLinesは、複数の文字列を行としてファイルに書き込むメソッドです。配列やIEnumerable<string>を渡せるため、一覧データの出力に向いています。

リストでも使えます。

C#
var lines = new List<string>
{
"Apple",
"Banana",
"Orange"
};

File.WriteAllLines("fruits.txt", lines);

自分で改行コードを連結しなくてよいため、コードがシンプルになります。

5-3. File.ReadAllLinesで行単位に読み込む

テキストファイルを行単位で読み込む場合は、File.ReadAllLinesを使います。

C#
string[] lines = File.ReadAllLines("sample.txt");

foreach (string line in lines)
{
Console.WriteLine(line);
}

ReadAllLinesを使うと、ファイル内の各行を配列として取得できます。通常、取得した各文字列には行末の改行コードは含まれません。

大きなファイルを扱う場合は、File.ReadLinesを使うと、必要に応じて行を列挙できます。

C#
foreach (string line in File.ReadLines("large.log"))
{
Console.WriteLine(line);
}

File.ReadLinesは行を列挙するメソッドで、大きなファイルを一度にすべて読み込まずに処理したい場合に便利です。

5-4. テキストファイル内の改行コードを判定する

ファイル内の改行コードを判定したい場合は、ファイル全体を文字列として読み込み、どの改行コードが含まれているか調べます。

C#
string text = File.ReadAllText("sample.txt");

if (text.Contains("\r\n"))
{
Console.WriteLine("CRLFが含まれています");
}
else if (text.Contains("\n"))
{
Console.WriteLine("LFが含まれています");
}
else if (text.Contains("\r"))
{
Console.WriteLine("CRが含まれています");
}
else
{
Console.WriteLine("改行コードは見つかりませんでした");
}

ただし、この方法では混在している場合の判定順に注意が必要です。\r\n\nも含むため、必ず\r\nを先に判定します。

より詳しく調べたい場合は、出現数を数えます。

C#
int crlfCount = text.Split("\r\n").Length - 1;
int lfCount = text.Replace("\r\n", "").Split('\n').Length - 1;
int crCount = text.Replace("\r\n", "").Split('\r').Length - 1;

Console.WriteLine($"CRLF: {crlfCount}");
Console.WriteLine($"LF: {lfCount}");
Console.WriteLine($"CR: {crCount}");

5-5. 改行コードを統一・変換する方法

改行コードを統一したい場合は、いったんすべての改行を\nにそろえてから、目的の改行コードに変換すると安全です。

C#
string text = File.ReadAllText("sample.txt");

// まずLFに統一
text = text.Replace("\r\n", "\n").Replace("\r", "\n");

// Windows形式のCRLFに変換
string crlfText = text.Replace("\n", "\r\n");

File.WriteAllText("sample_crlf.txt", crlfText);

LFに統一したい場合は、次のようにします。

C#
string text = File.ReadAllText("sample.txt");

text = text.Replace("\r\n", "\n").Replace("\r", "\n");

File.WriteAllText("sample_lf.txt", text);

ポイントは、\r\nを先に置換することです。先に\r\nを個別に置換すると、意図しない変換になることがあります。

5-6. WindowsとLinux間でファイルを扱うときの注意点

WindowsとLinuxの間でファイルを共有する場合、改行コードの違いに注意が必要です。

Windowsで作ったファイルはCRLF、Linuxで作ったファイルはLFになっていることが多いです。最近のエディタはどちらにも対応していますが、シェルスクリプト、設定ファイル、CSV連携、ログ解析ツールなどでは問題になる場合があります。

たとえば、Linux上で実行するシェルスクリプトにCRLFが含まれていると、実行時にエラーになることがあります。また、Windows向けの古いツールでは、LFだけのファイルを1行として表示してしまうことがあります。

C#でファイルを生成する場合は、誰が、どのOSで、どのツールを使って読むのかを考えて改行コードを選びましょう。

5-7. Gitやエディタ設定による改行コードの違い

Gitでは、設定によってコミット時やチェックアウト時に改行コードが変換されることがあります。

たとえば、Windows環境では作業ツリーでCRLF、リポジトリ内ではLFに変換される設定になっていることがあります。そのため、C#コードで出力したファイルの改行コードと、Gitで管理されているファイルの改行コードが異なる場合があります。

エディタ側でも、ファイルごとにCRLF・LFを選べることがあります。Visual Studio、Visual Studio Code、Riderなどを使っている場合は、画面下部や設定で現在の改行コードを確認できます。

チーム開発では、.editorconfig.gitattributesで改行コードの方針を決めておくと、環境差によるトラブルを減らせます。

6. 複数行文字列をきれいに扱う実践テクニック

6-1. StringBuilder.AppendLineで複数行を組み立てる

複数行の文字列を動的に組み立てる場合は、StringBuilder.AppendLineが便利です。

C#
var sb = new StringBuilder();

sb.AppendLine("商品一覧");
sb.AppendLine("--------");
sb.AppendLine("りんご");
sb.AppendLine("みかん");
sb.AppendLine("バナナ");

string result = sb.ToString();

Console.WriteLine(result);

AppendLineは、文字列を追加したあとに既定の行終端記号を追加します。Environment.NewLineと同様、環境に応じた改行を扱いやすい方法です。

ループで行を追加する場合にも向いています。

C#
var users = new[] { "田中", "佐藤", "鈴木" };
var sb = new StringBuilder();

foreach (string user in users)
{
sb.AppendLine(user);
}

Console.WriteLine(sb.ToString());

文字列連結を何度も繰り返すより、読みやすく効率的です。

6-2. string.Joinで配列やリストを改行区切りにする

配列やリストの要素を改行区切りの文字列にしたい場合は、string.Joinがシンプルです。

C#
string[] names = { "田中", "佐藤", "鈴木" };

string text = string.Join(Environment.NewLine, names);

Console.WriteLine(text);

出力結果は次のとおりです。

田中
佐藤
鈴木

LFで統一したい場合は、区切り文字に\nを指定します。

C#
string text = string.Join("\n", names);

CSVや外部API向けなど、仕様で改行コードが決まっている場合は、その仕様に合わせた区切り文字を使います。

6-3. 配列・Listの要素を1行ずつ出力する

配列やListを1行ずつConsoleに出力するだけなら、foreachConsole.WriteLineで十分です。

C#
var items = new List<string>
{
"A001",
"A002",
"A003"
};

foreach (string item in items)
{
Console.WriteLine(item);
}

ファイルに出力するなら、File.WriteAllLinesが使えます。

C#
File.WriteAllLines("items.txt", items);

文字列としてまとめたいなら、string.Joinを使います。

C#
string text = string.Join(Environment.NewLine, items);

同じ「1行ずつ」でも、表示するのか、ファイルへ書くのか、文字列として持つのかで選ぶメソッドが変わります。

6-4. インデントを崩さず複数行文字列を書く

複数行文字列を書くときに注意したいのが、インデントです。

逐語的文字列リテラルでは、コード上の空白がそのまま文字列に入ります。

C#
string text = @"    1行目
2行目";

この場合、各行の先頭に空白が含まれます。

raw string literalを使うと、終了のダブルクォート位置を基準にインデントを調整しやすくなります。

C#
string text = """
1行目
2行目
3行目
""";

JSONやHTMLのようにインデントが意味を持つ、または読みやすさに関わるテキストでは、raw string literalを使うと見た目と実際の文字列を近づけやすくなります。

6-5. ログ・メール本文・メッセージ文での改行の書き方

ログを組み立てる場合は、StringBuilder.AppendLineが向いています。

C#
var sb = new StringBuilder();

sb.AppendLine("[INFO] 処理開始");
sb.AppendLine("[INFO] データ取得完了");
sb.AppendLine("[INFO] 処理終了");

string log = sb.ToString();

メール本文のように固定文が多い場合は、raw string literalが読みやすいです。

C#
string body = """
山田様

お世話になっております。
ご依頼いただいた件について、資料を添付いたします。

ご確認のほどよろしくお願いいたします。
""";

ユーザー向けの短いメッセージなら、Environment.NewLineで組み立ててもよいでしょう。

C#
string message =
"登録が完了しました。" + Environment.NewLine +
"確認メールをご確認ください。";

用途に応じて、読みやすさを優先して選ぶことが大切です。

6-6. 可読性が高い改行コードの書き分け例

可読性を意識すると、次のように使い分けるのがおすすめです。

短い固定メッセージなら\nでも問題ありません。

C#
string message = "成功しました。\n次の処理に進みます。";

環境に合わせたいアプリ内メッセージならEnvironment.NewLineを使います。

C#
string message = $"名前: {name}{Environment.NewLine}年齢: {age}";

複数行をループで作るならStringBuilder.AppendLineが読みやすいです。

C#
var sb = new StringBuilder();

foreach (var error in errors)
{
sb.AppendLine(error.Message);
}

配列やListを区切るだけならstring.Joinが最も簡潔です。

C#
string text = string.Join(Environment.NewLine, lines);

長い固定テキストならraw string literalが自然です。

C#
string template = """
ご担当者様

以下の内容をご確認ください。

よろしくお願いいたします。
""";

7. UI・Web・データ形式で改行を扱うときの注意点

7-1. Windows FormsのTextBoxで改行する方法

Windows FormsのTextBoxで複数行を表示するには、Multilinetrueにする必要があります。

C#
textBox1.Multiline = true;
textBox1.Text = "1行目\r\n2行目";

または、Environment.NewLineを使います。

C#
textBox1.Multiline = true;
textBox1.Text = "1行目" + Environment.NewLine + "2行目";

Multilinefalseのままだと、改行コードを入れても期待どおりに複数行表示されないことがあります。

スクロールバーを表示したい場合は、次のように設定します。

C#
textBox1.Multiline = true;
textBox1.ScrollBars = ScrollBars.Vertical;

Windows Formsでは、TextBoxの設定と改行コードの両方を確認することが大切です。

7-2. WPFのTextBoxやTextBlockで改行する方法

WPFのTextBoxでも、複数行入力を許可するには設定が必要です。

XML
<TextBox AcceptsReturn="True" TextWrapping="Wrap" />

C#側から文字列を設定する場合は、次のように書けます。

C#
textBox.Text = "1行目" + Environment.NewLine + "2行目";

TextBlockでは、文字列に改行を含めることで複数行表示できます。

XML
<TextBlock Text="1行目&#x0a;2行目" />

C#側なら次のように書けます。

C#
textBlock.Text = "1行目\n2行目";

WPFでは、入力用のTextBoxと表示用のTextBlockで設定が異なる点に注意しましょう。

7-3. ASP.NETやHTMLでは改行コードだけでは表示が変わらない理由

ASP.NETでC#の文字列に\nEnvironment.NewLineを入れても、HTMLとして表示したときに改行されないことがあります。

理由は、HTMLでは通常の空白や改行が表示上まとめて扱われるためです。

たとえば、C#側で次の文字列を作ったとします。

C#
string message = "1行目\n2行目";

これをHTMLにそのまま出力しても、ブラウザ上では次のように1行に見えることがあります。

1行目 2行目

HTML画面で改行として見せたい場合は、<br>に変換するか、CSSのwhite-spaceを使う必要があります。

7-4. HTMLで改行表示するbrタグとの違い

C#の改行コードとHTMLの<br>は別物です。

C#の改行コードは、文字列データ内の行区切りです。

C#
string text = "1行目\n2行目";

HTMLの<br>は、ブラウザに「ここで改行して表示する」と指示するタグです。

HTML
1行目<br>2行目

C#文字列内の改行をHTML表示用に変換する例は次のとおりです。

C#
string text = "1行目\n2行目";
string html = text.Replace("\n", "<br>");

ただし、ユーザー入力をHTMLに表示する場合は、HTMLエスケープを必ず考慮してください。単純にReplaceするだけだと、XSSなどのセキュリティ問題につながる可能性があります。

CSSで表示だけ改行を反映したい場合は、white-space: pre-line;を使う方法もあります。

HTML
<div style="white-space: pre-line;">
1行目
2行目
</div>

7-5. JSON文字列で改行を扱う方法

JSON文字列内で改行を表す場合は、通常\nとしてエスケープされます。

C#でJSON用の文字列を手作業で組み立てると、エスケープが複雑になりやすいため注意が必要です。

C#
string message = "1行目\n2行目";

この文字列をJSONにすると、JSON上では次のように表現されます。

JSON
{
"message": "1行目\n2行目"
}

C#でJSONを扱う場合は、手動で文字列連結するより、System.Text.Jsonなどのシリアライザーを使うのが安全です。

C#
var data = new
{
message = "1行目\n2行目"
};

string json = JsonSerializer.Serialize(data);

JSON本文をソースコードに書きたい場合は、raw string literalを使うと読みやすくなります。

C#
string json = """
{
"message": "1行目\n2行目"
}
""";

7-6. CSVやログファイルで改行を扱うときの注意点

CSVでは、セル内に改行を含める場合があります。その場合、値をダブルクォートで囲む必要があるなど、CSVのルールに従う必要があります。

csv
id,comment
1,"1行目
2行目"

C#でCSVを単純にカンマ連結で作ると、改行を含むデータで壊れることがあります。

C#
string line = id + "," + comment;

commentに改行が含まれていると、1レコードが複数行に分かれてしまう場合があります。CSVを扱う場合は、CSVライブラリを使うか、引用符やエスケープを正しく処理しましょう。

ログファイルでは、1ログ1行の前提で解析することが多いため、メッセージ内に改行が含まれるとログ解析が難しくなります。

必要に応じて、改行をスペースや\nの文字表現に置き換える方法があります。

C#
string safeMessage = message.Replace("\r\n", "\\n")
.Replace("\n", "\\n")
.Replace("\r", "\\n");

8. C#の改行でよくあるエラー・トラブル解決

8-1. \nを書いたのに改行されない

\nを書いたのに改行されない場合、まず文字列の書き方を確認します。

次のコードでは改行されます。

C#
Console.WriteLine("1行目\n2行目");

しかし、次のコードでは改行されません。

C#
Console.WriteLine(@"1行目\n2行目");

@付きの逐語的文字列リテラルでは、\nは改行ではなく、バックスラッシュとnとして扱われます。

また、HTMLに表示している場合も、\nだけではブラウザ上の改行として表示されないことがあります。その場合は<br>やCSSを使います。

8-2. \nがそのまま文字として表示される

画面に\nがそのまま表示される場合は、文字列に実際の改行コードではなく、バックスラッシュとnの2文字が入っている可能性があります。

たとえば、次のような文字列です。

C#
string text = "1行目\\n2行目";

この場合、出力は次のようになります。

1行目\n2行目

実際の改行に変換したい場合は、次のように置換します。

C#
text = text.Replace("\\n", "\n");

JSONや外部ファイルから読み込んだ文字列では、エスケープされた\nと実際の改行が混同されることがあるため注意しましょう。

8-3. 改行コードが二重に入って空行が増える

空行が増える場合は、すでに改行を含む文字列に対して、さらにWriteLineAppendLineを使っている可能性があります。

C#
Console.WriteLine("1行目\n");
Console.WriteLine("2行目");

この場合、"1行目\n"の末尾改行とWriteLineの自動改行が重なり、空行が出ることがあります。

対策として、末尾の改行を削除します。

C#
string text = "1行目\n";
Console.WriteLine(text.TrimEnd('\r', '\n'));

または、改行を自分で制御したい場合はConsole.Writeを使います。

C#
Console.Write("1行目\n");
Console.Write("2行目");

8-4. Windowsでは正常なのにLinuxで表示が崩れる

Windowsでは正常なのにLinuxで表示が崩れる場合は、改行コードの違いが原因かもしれません。

Windows向けに\r\nで出力したファイルをLinuxのツールで処理すると、行末に余分な\rが残ることがあります。逆に、Linuxの\nだけのファイルを古いWindowsツールで開くと、改行されないことがあります。

クロスプラットフォームで動くC#アプリでは、次のように考えます。

C#
// OSに合わせる
string text = string.Join(Environment.NewLine, lines);

// LFに統一する
string textForLinux = string.Join("\n", lines);

// CRLFに統一する
string textForWindows = string.Join("\r\n", lines);

実行環境に合わせるのか、ファイル仕様に合わせるのかを明確にしましょう。

8-5. テキストボックスで改行が反映されない

Windows FormsやWPFのTextBoxで改行が反映されない場合は、複数行表示や入力が有効になっているか確認します。

Windows Formsでは、Multilineが必要です。

C#
textBox1.Multiline = true;
textBox1.Text = "1行目" + Environment.NewLine + "2行目";

WPFのTextBoxでEnter入力を許可するには、AcceptsReturnを設定します。

XML
<TextBox AcceptsReturn="True" />

文字列に改行コードが入っていても、UI部品側が複数行表示に対応する設定になっていなければ、期待どおりに表示されないことがあります。

8-6. ファイル読み込み後に改行コードが混在する

外部から受け取ったファイルや、複数人で編集されたファイルでは、CRLFとLFが混在していることがあります。

混在を解消するには、読み込み後に改行コードを統一します。

C#
string text = File.ReadAllText("input.txt");

text = text.Replace("\r\n", "\n")
.Replace("\r", "\n");

File.WriteAllText("output.txt", text);

Windows形式にしたい場合は、その後でCRLFへ変換します。

C#
text = text.Replace("\n", "\r\n");

このように、いったんLFへ正規化してから目的の改行コードへ変換すると、処理が安定します。

8-7. コピー&ペーストで改行が崩れる

Webページ、Excel、チャットツール、メールソフトなどから文字列をコピーすると、改行コードが変わったり、余分な空白が入ったりすることがあります。

特に、次のようなケースに注意が必要です。

コピー元起こりやすい問題
Excelセル内改行やタブが混ざる
Webページ空白やHTML由来の改行が入る
メールCRLFが混ざる
チャット見た目と実際の改行が異なる

C#で受け取った文字列を処理する前に、改行コードを正規化すると安全です。

C#
string NormalizeNewLine(string text)
{
return text.Replace("\r\n", "\n")
.Replace("\r", "\n");
}

入力データを扱う処理では、「見た目どおりの改行が入っている」と決めつけないことが大切です。

9. C#の改行コードの使い分け早見表

9-1. 文字列内で簡単に改行したい場合

簡単な文字列内改行なら、\nが最も手軽です。

C#
string text = "1行目\n2行目";

短いメッセージやコード例では、\nで十分な場面が多いです。

ただし、OSに合わせた改行にしたい場合は、Environment.NewLineを使います。

C#
string text = "1行目" + Environment.NewLine + "2行目";

9-2. コンソールに1行ずつ表示したい場合

コンソールに1行ずつ表示するなら、Console.WriteLineを使います。

C#
Console.WriteLine("1行目");
Console.WriteLine("2行目");

WriteLineは自動的に改行するため、自分で改行コードを付ける必要はありません。

同じ行に続けて表示したい場合は、Console.Writeを使います。

C#
Console.Write("入力してください: ");

9-3. OSに依存しない改行を使いたい場合

実行環境に合わせた改行を使いたい場合は、Environment.NewLineです。

C#
string text = string.Join(Environment.NewLine, lines);

Windows、Linux、macOSで自然な改行を使いたいアプリケーションでは、Environment.NewLineが便利です。

ただし、外部仕様で改行コードが決まっている場合は、その仕様を優先します。

9-4. ファイルへ複数行を書き込みたい場合

配列やリストをファイルへ複数行で書き込むなら、File.WriteAllLinesが簡単です。

C#
File.WriteAllLines("output.txt", lines);

細かく制御したい場合は、StreamWriterを使います。

C#
using var writer = new StreamWriter("output.txt");

foreach (string line in lines)
{
writer.WriteLine(line);
}

改行コードを明示的に統一したい場合は、string.Joinで改行コードを指定してから書き込みます。

C#
File.WriteAllText("output.txt", string.Join("\n", lines));

9-5. Web画面で改行を表示したい場合

Web画面で改行を表示したい場合、C#の\nだけでは不十分なことがあります。

HTMLで明示的に改行したいなら、<br>を使います。

C#
string html = text.Replace("\n", "<br>");

ただし、ユーザー入力をHTMLに出す場合は、HTMLエスケープを忘れてはいけません。

CSSで改行を反映したい場合は、white-space: pre-line;を使う方法もあります。

HTML
<div style="white-space: pre-line;">...</div>

9-6. 複数行テキストを効率よく組み立てたい場合

複数行テキストを動的に組み立てるなら、StringBuilder.AppendLineが便利です。

C#
var sb = new StringBuilder();

sb.AppendLine("1行目");
sb.AppendLine("2行目");
sb.AppendLine("3行目");

string text = sb.ToString();

配列やリストを単純に改行区切りにしたいだけなら、string.Joinが簡潔です。

C#
string text = string.Join(Environment.NewLine, lines);

固定の長い文章なら、raw string literalを使うと読みやすくなります。

C#
string text = """
1行目
2行目
3行目
""";

10. C#の改行コードに関するよくある質問

10-1. C#では\nとEnvironment.NewLineのどちらを使うべきか

どちらを使うべきかは、目的によって変わります。

簡単な文字列や、仕様としてLFでよい場面では\nで問題ありません。

C#
string text = "A\nB";

実行環境に合わせた改行にしたい場合は、Environment.NewLineを使います。

C#
string text = "A" + Environment.NewLine + "B";

外部API、設定ファイル、CSV、プロトコルなどで改行コードが決まっている場合は、Environment.NewLineではなく仕様で指定された改行コードを使います。

10-2. \r\nと\nはどちらが正しいのか

どちらも正しい改行コードです。ただし、使われる環境や用途が違います。

\r\nはWindowsでよく使われる改行コードです。\nはLinuxやmacOSでよく使われる改行コードです。

C#としてどちらが正しいかではなく、出力先が何を期待しているかで決めます。

C#
// Windows形式
string crlf = "1行目\r\n2行目";

// LF形式
string lf = "1行目\n2行目";

迷った場合は、OSに合わせるならEnvironment.NewLine、仕様に合わせるなら仕様で決められた改行コードを使います。

10-3. Console.WriteLineはどの改行コードを使うのか

Console.WriteLineは、文字列を出力したあとに改行を追加します。この改行には、実行環境に応じた行終端が使われます。

MicrosoftのEnvironment.NewLineの説明では、Console.WriteLineStringBuilder.AppendLineによって処理されるテキストにはNewLineが自動的に追加されるとされています。

そのため、通常のコンソール出力では次のように書けば十分です。

C#
Console.WriteLine("1行目");
Console.WriteLine("2行目");

自分で末尾に\nを付ける必要はありません。

10-4. 文字列内で直接改行してもよいのか

通常の文字列リテラルでは、文字列内にそのまま改行を書くことはできません。

C#
// 通常の文字列では不可
string text = "1行目
2行目";

複数行文字列を書きたい場合は、逐語的文字列リテラルやraw string literalを使います。

C#
string text1 = @"1行目
2行目";

C# 11以降なら、raw string literalが読みやすいです。

C#
string text2 = """
1行目
2行目
""";

短い改行なら\n、長い複数行テキストならraw string literalという使い分けがおすすめです。

10-5. 改行コードを削除・置換するにはどうすればよいか

改行コードを削除するには、\r\n\n\rを置換します。

C#
string text = "1行目\r\n2行目\n3行目";

string noNewLine = text.Replace("\r\n", "")
.Replace("\n", "")
.Replace("\r", "");

スペースに置き換えたい場合は、次のようにします。

C#
string oneLine = text.Replace("\r\n", " ")
.Replace("\n", " ")
.Replace("\r", " ");

改行コードをLFに統一する場合は、次のようにします。

C#
string normalized = text.Replace("\r\n", "\n")
.Replace("\r", "\n");

CRLFに統一する場合は、いったんLFへ統一してから変換します。

C#
string normalized = text.Replace("\r\n", "\n")
.Replace("\r", "\n");

string crlf = normalized.Replace("\n", "\r\n");

10-6. C#で改行コードを判定するにはどうすればよいか

文字列に含まれる改行コードを判定するには、Containsを使います。

C#
if (text.Contains("\r\n"))
{
Console.WriteLine("CRLFが含まれています");
}
else if (text.Contains("\n"))
{
Console.WriteLine("LFが含まれています");
}
else if (text.Contains("\r"))
{
Console.WriteLine("CRが含まれています");
}

重要なのは、\r\nを先に判定することです。\r\nには\nも含まれるため、先に\nを判定するとCRLFの判定が正しくできません。

混在を調べたい場合は、正規化しながら数える方法もあります。

C#
bool hasCrlf = text.Contains("\r\n");
bool hasLfOnly = text.Replace("\r\n", "").Contains("\n");
bool hasCrOnly = text.Replace("\r\n", "").Contains("\r");

Console.WriteLine($"CRLF: {hasCrlf}");
Console.WriteLine($"LF only: {hasLfOnly}");
Console.WriteLine($"CR only: {hasCrOnly}");

ファイルの改行コードを調べる場合は、File.ReadAllTextで読み込んでから同じように判定できます。

まとめ

C#の改行コードは、文字列・Console・ファイル・UI・Webなど、使う場所によって適切な書き方が変わります。

文字列内で手軽に改行したい場合は\n、Windows向けに明示したい場合は\r\n、実行環境に合わせたい場合はEnvironment.NewLineを使います。コンソールに1行ずつ表示するならConsole.WriteLine、複数行を動的に組み立てるならStringBuilder.AppendLinestring.Joinが便利です。

ファイル出力では、WindowsとLinuxで改行コードが異なる点に注意しましょう。外部システムやAPI、CSV、ログ、設定ファイルなどでは、実行環境ではなく仕様に合わせた改行コードを使うことが重要です。

また、ASP.NETやHTMLでは、C#の改行コードを入れただけではブラウザ上で改行表示されないことがあります。Web画面では<br>やCSSのwhite-spaceを使う必要があります。

C#の改行で迷ったときは、次のように考えると整理しやすくなります。

やりたいこと使うもの
文字列内で簡単に改行する\n
Windows形式で改行する\r\n
OSに合わせて改行するEnvironment.NewLine
Consoleに1行ずつ出すConsole.WriteLine
複数行を組み立てるStringBuilder.AppendLine
配列を改行区切りにするstring.Join
ファイルへ行単位で書くFile.WriteAllLines
HTMLで改行表示する<br>またはCSS

「C# 改行」は単純に見えて、OS、表示先、ファイル形式、外部仕様が関係する重要なポイントです。用途に合わせて改行コードを正しく使い分けることで、表示崩れやファイル処理のトラブルを防ぐことができます。