C#で改行する方法まとめ|文字列の改行コード(\n・Environment.NewLine)と出力例を解説

はじめに

C#で文字列やメッセージを複数行に分けたい場合は、改行コードを文字列に含める方法や、改行を伴う出力メソッドを利用します。

代表的な方法は、次の2つです。

C#
string text1 = "1行目\n2行目";
string text2 = "1行目" + Environment.NewLine + "2行目";

\nはLFと呼ばれる改行文字です。一方、Environment.NewLineは、プログラムを実行しているOSに適した改行文字列を返します。

ただし、コンソール、ファイル、テキストボックス、HTMLなど、出力先によって適切な改行方法は異なります。本記事では、C#で改行する基本から、改行コードの違い、複数行文字列の作成、置換・削除・分割、よくあるトラブルまで、サンプルコード付きで解説します。

1. C#で改行する方法の基本

1-1. C#で改行したい場面とは

C#で改行が必要になる代表的な場面には、次のようなものがあります。

  • コンソールに複数行のメッセージを表示する

  • テキストファイルへ行単位でデータを書き込む

  • WindowsフォームやWPFのテキストボックスに複数行を表示する

  • ログメッセージを読みやすく整形する

  • 配列やリストの要素を1行ずつ出力する

  • メール本文や帳票用の文章を作る

  • 複数行のSQLやJSON、XMLを文字列として記述する

C#では、文字列内に改行コードを含める方法だけでなく、Console.WriteLineStreamWriter.WriteLineのように、出力時に自動で改行するメソッドも利用できます。

目的や出力先に応じて使い分けることが重要です。

1-2. 文字列内で改行する主な方法

C#で文字列を改行する主な方法は、次のとおりです。

C#
// \nを使う
string text1 = "1行目\n2行目";

// Environment.NewLineを使う
string text2 = "1行目" + Environment.NewLine + "2行目";

// 逐語的文字列リテラルを使う
string text3 = @"1行目
2行目";

// Raw文字列リテラルを使う(C# 11以降)
string text4 = """
1行目
2行目
""";

単純な短い文字列には\n、実行環境の改行コードを使いたい場合にはEnvironment.NewLineが適しています。

文章やテンプレートを複数行で記述したい場合は、逐語的文字列リテラルやRaw文字列リテラルを使うと、コードが読みやすくなります。

1-3. まず覚えるべき「\n」と「Environment.NewLine」の違い

\nEnvironment.NewLineの大きな違いは、改行文字が固定か、実行環境によって変わるかです。

C#
string lf = "\n";
string platformNewLine = Environment.NewLine;

\nは常にLFを表します。

一方、Environment.NewLineは、一般的に次の値を返します。

  • Windows:\r\n

  • Linux:\n

  • macOS:\n

現在の.NETでは、多くのAPIやエディタがLFとCRLFの両方を扱えます。そのため、画面表示や内部処理では\nで問題ないケースも少なくありません。

ただし、OS標準の形式でテキストファイルを作成したい場合や、環境依存の出力仕様に合わせたい場合は、Environment.NewLineが適しています。

2. \nを使って文字列を改行する方法

2-1. \nとは何か

\nは、改行を表すエスケープシーケンスです。文字コードとしてはLF(Line Feed)を表します。

C#
char lineFeed = '\n';

C#の通常の文字列リテラルでは、バックスラッシュから始まる特別な文字列をエスケープシーケンスとして解釈します。

代表的なエスケープシーケンスは次のとおりです。

記述意味
\n改行、LF
\r復帰、CR
\tタブ
\\バックスラッシュ
\"ダブルクォーテーション

\nは1文字なので、短い文字列の途中へ簡単に挿入できます。

2-2. 文字列の途中に\nを入れる基本例

文字列の途中に\nを記述すると、その位置で改行されます。

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

Console.WriteLine(message);

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

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

3行以上に分ける場合も、改行したい位置へ\nを追加します。

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

Console.WriteLine(message);
1行目
2行目
3行目

2-3. Console.WriteLineで\nを使う出力例

Console.WriteLineは、文字列を出力した後に自動で改行します。引数の文字列内に\nを含めることも可能です。

C#
Console.WriteLine("商品名:ノートPC\n価格:100,000円");

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

商品名:ノートPC
価格:100,000円

このコードでは、\nによって「価格」の前で改行され、さらにConsole.WriteLineによって最後にも改行が追加されます。

末尾に余分な改行を加えたくない場合は、Console.Writeを使います。

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

Console.Writeは、出力後に自動で改行しません。

2-4. 複数行の文字列を\nで作る例

複数の情報を1つの文字列にまとめる場合も、\nを利用できます。

C#
string name = "山田太郎";
int age = 30;
string city = "東京都";

string profile =
$"名前:{name}\n" +
$"年齢:{age}\n" +
$"住所:{city}";

Console.WriteLine(profile);

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

名前:山田太郎
年齢:30
住所:東京都

文字列補間を使うと、変数の値を埋め込みながら改行できます。

2-5. \nを使うときの注意点

\nを使う際は、次の点に注意が必要です。

1つ目は、Windows標準の改行コードが一般的に\r\nであることです。アプリケーション上では\nだけでも改行されることが多いものの、古いソフトウェアや特定の外部システムでは、\r\nを要求されることがあります。

2つ目は、逐語的文字列リテラル内では\nが改行として解釈されないことです。

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

Console.WriteLine(text);

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

1行目\n2行目

@を付けた逐語的文字列リテラルでは、バックスラッシュが通常の文字として扱われます。逐語的文字列で改行したい場合は、ソースコード上で実際に改行します。

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

3. Environment.NewLineを使って改行する方法

3-1. Environment.NewLineとは何か

Environment.NewLineは、現在の実行環境で使用される改行文字列を取得するプロパティです。

C#
string newLine = Environment.NewLine;

Environment.NewLineの型はstringです。\nが1文字のLFを表すのに対し、WindowsのEnvironment.NewLineは通常、CRとLFを組み合わせた2文字の\r\nになります。

実行環境に合った改行コードを使えるため、OS標準のテキストを作成するときに便利です。

3-2. Environment.NewLineの基本的な使い方

文字列の間にEnvironment.NewLineを連結します。

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

Console.WriteLine(message);

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

1行目
2行目

文字列補間の中に直接記述することもできます。

C#
string message = $"1行目{Environment.NewLine}2行目";

Console.WriteLine(message);

繰り返し使用する場合は、ローカル変数へ代入して記述を短くできます。

C#
string nl = Environment.NewLine;
string message = $"名前:山田{nl}年齢:30{nl}住所:東京";

3-3. Console.WriteLineでEnvironment.NewLineを使う出力例

Console.WriteLineEnvironment.NewLineを組み合わせる例は次のとおりです。

C#
string result =
"処理を開始しました。" +
Environment.NewLine +
"処理中です。" +
Environment.NewLine +
"処理が完了しました。";

Console.WriteLine(result);

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

処理を開始しました。
処理中です。
処理が完了しました。

なお、1行ずつ出力するだけなら、複数回Console.WriteLineを呼び出す方法も簡単です。

C#
Console.WriteLine("処理を開始しました。");
Console.WriteLine("処理中です。");
Console.WriteLine("処理が完了しました。");

文字列そのものを後からファイル保存したり、別のメソッドに渡したりする場合は、Environment.NewLineで1つの文字列にまとめる方法が適しています。

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

改行コードの違いは、各OSやコンピューターシステムの歴史的な仕様に由来します。

Windowsでは、一般的にCRLFが使用されます。

\r\n

Linuxや現在のmacOSでは、一般的にLFが使用されます。

\n

古いMac OSではCRが使用されていました。

\r

.NETアプリケーションを複数のOSで動かす場合、Environment.NewLineを使うと実行環境に合った改行コードを取得できます。

C#
Console.WriteLine(
BitConverter.ToString(
System.Text.Encoding.UTF8.GetBytes(Environment.NewLine)
)
);

Windowsでは通常0D-0A、LinuxやmacOSでは通常0Aが出力されます。

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

次のようなケースでは、\nよりEnvironment.NewLineが適しています。

  • 実行中のOSに合わせてテキストファイルを作成する

  • OS標準の改行形式を要求する外部ソフトウェアと連携する

  • 人がエディタで読むログや帳票データを作成する

  • Windows専用アプリケーションでCRLFを明示的に利用したい

  • プラットフォーム固有の書式を保ちたい

一方、HTTP、JSON Lines、Git管理下のソースファイルなど、仕様やプロジェクトルールによってLFへ統一する場合は、Environment.NewLineではなく\nを明示的に使うほうが適切です。

「常にEnvironment.NewLineを使えばよい」というわけではなく、データの仕様と利用目的に合わせて選びます。

4. C#の改行コードの種類と違い

4-1. LF(\n)とは

LFは「Line Feed」の略で、次の行へ移動するための制御文字です。

C#では\nと記述します。

C#
string text = "A\nB";

文字コードの値は、10進数で10、16進数で0Aです。

Linuxや現在のmacOSでは、テキストファイルの改行コードとして一般的にLFが使われます。Web開発やクロスプラットフォーム開発でも、LFへ統一するケースが多くあります。

4-2. CRLF(\r\n)とは

CRLFは、CRとLFを組み合わせた改行コードです。

C#
string text = "A\r\nB";

CRは「Carriage Return」、LFは「Line Feed」を意味します。

文字コードの値は次の組み合わせです。

CR:0D
LF:0A

Windowsのテキストファイルでは、一般的にCRLFが使われます。

C#でWindowsの改行を明示する場合は、次のように記述できます。

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

ただし、OSに応じて切り替えたい場合は、直接\r\nを書くよりEnvironment.NewLineを利用するほうが適しています。

4-3. CR(\r)とは

CRは「Carriage Return」の略で、カーソルを現在行の先頭へ戻す制御文字です。

C#
Console.Write("12345\rABC");

実行環境によって表示は異なりますが、同じ行の先頭から文字を上書きするような動作になります。

CRだけを行区切りとして使う形式は、現在の一般的なテキストファイルではほとんど使われません。ただし、古いMac OS由来のデータや、特殊な通信データを扱うときに登場する場合があります。

進捗表示を同じ行で更新するときに\rを使うこともあります。

C#
for (int i = 0; i <= 100; i++)
{
Console.Write($"\r進捗:{i}%");
Thread.Sleep(20);
}

4-4. C#でよく使われる改行コード

C#でよく利用する改行の記述を整理すると、次のようになります。

記述内容主な用途
\nLF内部文字列、Linux、Web、LF統一
\r\nCRLFWindows形式を明示する場合
\rCR行頭への復帰、特殊なデータ
Environment.NewLine実行OSに応じた改行OS標準のファイルや表示
Console.WriteLine出力後に改行コンソール出力
StringBuilder.AppendLine文字列追加後に改行複数行文字列の組み立て

単純な画面表示では\n、OS標準のファイルではEnvironment.NewLine、大量の文字列を組み立てる場合はStringBuilder.AppendLineが代表的な選択肢です。

4-5. 改行コードの違いで起きやすいトラブル

改行コードが異なると、次のようなトラブルが起こることがあります。

  • エディタ上で改行されず、記号のように表示される

  • 行末に不要な^Mが表示される

  • Gitでファイル全体が変更されたように見える

  • CSVや固定長データを外部システムが読み込めない

  • 改行で分割したつもりなのに末尾へ\rが残る

  • 単体テストで期待値と実際の文字列が一致しない

  • OSを変えるとテストが失敗する

たとえば、CRLFの文字列を\nだけで分割すると、各行の末尾に\rが残る場合があります。

C#
string text = "A\r\nB\r\nC";
string[] lines = text.Split('\n');

foreach (string line in lines)
{
Console.WriteLine($"[{line}]");
}

環境に依存しない処理が必要な場合は、CRLFとLFの両方を考慮して正規化します。

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

5. 文字列リテラルで改行を扱う方法

5-1. 通常の文字列で改行する方法

通常の文字列リテラルでは、\n\r\nを使って改行します。

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

通常の文字列をソースコード上でそのまま複数行に分けることはできません。

次のコードはコンパイルエラーになります。

C#
// コンパイルエラー
string message = "1行目
2行目";

長い文字列を複数行に分けて記述したい場合は、文字列を連結します。

C#
string message =
"これは長い文章です。" +
"ソースコード上では複数行に分けています。" +
"文字列内には改行されません。";

文字列内にも改行を入れる場合は、\nなどを追加します。

C#
string message =
"1行目です。\n" +
"2行目です。\n" +
"3行目です。";

5-2. 逐語的文字列リテラル(@)で複数行を書く方法

文字列の先頭に@を付けると、逐語的文字列リテラルになります。

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

ソースコード上の改行が、そのまま文字列に含まれます。

逐語的文字列リテラルでは、バックスラッシュをエスケープする必要がありません。

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

ただし、ダブルクォーテーションを含める場合は、2つ重ねます。

C#
string message = @"彼は""こんにちは""と言いました。";

逐語的文字列リテラル内の改行コードは、通常、ソースファイル自体の改行形式の影響を受けます。そのため、データ仕様としてLFやCRLFを厳密に固定したい場合は、\n\r\nを明示する方法が安全です。

5-3. 文字列補間($)と改行を組み合わせる方法

文字列補間を使うと、変数の値を埋め込みながら改行できます。

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

string result = $"氏名:{name}\n得点:{score}点";

Console.WriteLine(result);

Environment.NewLineも埋め込めます。

C#
string result =
$"氏名:{name}{Environment.NewLine}" +
$"得点:{score}点";

$@を組み合わせると、変数を含む複数行文字列を記述できます。

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

string result = $@"成績表
氏名:{name}
得点:{score}点";

Console.WriteLine(result);

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

成績表
氏名:佐藤
得点:85点

5-4. Raw文字列リテラルで複数行を書く方法

C# 11以降では、3つ以上のダブルクォーテーションを使ったRaw文字列リテラルを利用できます。

C#
string message = """
1行目です。
2行目です。
3行目です。
""";

Raw文字列リテラルでは、ダブルクォーテーションやバックスラッシュをエスケープせずに記述しやすくなります。

C#
string json = """
{
"name": "山田太郎",
"message": "C:\work\sample"
}
""";

文字列補間を組み合わせる場合は、$を付けます。

C#
string name = "山田太郎";
int age = 30;

string profile = $"""
名前:{name}
年齢:{age}
""";

JSONやHTML、SQLなど、ダブルクォーテーションや改行を多く含む文字列では、Raw文字列リテラルを使うと読みやすくなります。

5-5. 読みやすい複数行文字列の書き方

短いメッセージなら、\nを使った記述で十分です。

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

文章が長い場合や、レイアウトを見ながら編集したい場合は、Raw文字列リテラルが適しています。

C#
string mailBody = """
お世話になっております。

ご依頼いただいた資料を送付いたします。
ご確認をお願いいたします。
""";

動的に多くの行を追加する場合は、StringBuilderを使います。

C#
var builder = new StringBuilder();

builder.AppendLine("処理結果");
builder.AppendLine("----------");
builder.AppendLine("成功:10件");
builder.AppendLine("失敗:0件");

string result = builder.ToString();

文字列の長さ、変更頻度、改行コードの仕様を考慮して方法を選ぶと、読みやすく保守しやすいコードになります。

6. 出力先別の改行方法

6-1. コンソールに改行して表示する方法

コンソールへ1行ずつ表示する場合は、Console.WriteLineを使います。

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

1つの文字列内で改行する場合は、\nまたはEnvironment.NewLineを使います。

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

空行を出力する場合は、引数なしでConsole.WriteLineを呼び出します。

C#
Console.WriteLine("上の行");
Console.WriteLine();
Console.WriteLine("下の行");

Console.Writeは末尾で改行しません。

C#
Console.Write("名前:");
Console.WriteLine("山田太郎");

同じ行に続けて表示したいときはConsole.Write、出力後に次の行へ移動したいときはConsole.WriteLineを使います。

6-2. ファイルに改行付きで書き込む方法

ファイルに複数行を書き込む場合は、File.WriteAllLinesが便利です。

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

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

1つの文字列として書き込む場合は、改行を含めてFile.WriteAllTextへ渡します。

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

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

行を順番に追加する場合は、StreamWriter.WriteLineを使います。

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

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

特定の改行コードへ固定したい場合は、StreamWriter.NewLineを設定できます。

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

writer.NewLine = "\n";
writer.WriteLine("1行目");
writer.WriteLine("2行目");

この例では、実行OSに関係なくLFで出力されます。

6-3. テキストボックスで改行を表示する方法

WinFormsのTextBoxで複数行を表示するには、Multilinetrueにします。

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

フォームデザイナーを使う場合は、MultilineプロパティをTrueに設定します。必要に応じてスクロールバーも設定します。

C#
textBox1.ScrollBars = ScrollBars.Vertical;

WPFのTextBoxでは、AcceptsReturnを有効にするとEnterキーによる改行入力を受け付けます。

XML
<TextBox
x:Name="InputTextBox"
AcceptsReturn="True"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />

コードから複数行を設定する例は次のとおりです。

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

WinFormsで改行されない場合は、まずMultilineが有効になっているか確認します。

6-4. HTMLに出力するときの改行の考え方

HTMLでは、文字列に\nが含まれていても、通常の表示ではそのまま改行されません。

たとえば、次のHTMLではソースコードに改行があっても、ブラウザ上では空白としてまとめられることがあります。

HTML
<div>
1行目
2行目
</div>

HTML上で明示的に改行する場合は、<br>を使います。

C#
string html = "1行目<br>2行目";

ただし、ユーザー入力をHTMLへ出力する場合、単純に改行だけを<br>へ置換すると、HTMLタグやスクリプトが混入する危険があります。先にHTMLエンコードし、その後で改行を<br>へ変換します。

ASP.NET Coreでは、次のような考え方になります。

C#
using System.Net;

string input = "1行目\n2行目";
string encoded = WebUtility.HtmlEncode(input);
string html = encoded.Replace("\n", "<br>");

CSSのwhite-spaceを利用する方法もあります。

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

HTMLでは、C#の改行コードとブラウザ上の改行表示を分けて考える必要があります。

6-5. ログ出力で改行を使うときの注意点

ログメッセージに改行を含めると、人間には読みやすくなる一方で、ログ解析ツールが1件のログを複数件として認識する場合があります。

C#
logger.LogInformation(
"処理結果:{NewLine}成功: {Success}{NewLine}失敗: {Failure}",
Environment.NewLine,
successCount,
failureCount
);

構造化ログを利用している場合は、1つのメッセージへ複数行を詰め込むより、値を個別のプロパティとして記録するほうが扱いやすくなります。

C#
logger.LogInformation(
"処理が完了しました。成功: {SuccessCount}件、失敗: {FailureCount}件",
successCount,
failureCount
);

また、外部入力をそのままログへ記録すると、改行を悪用して偽のログ行を追加される可能性があります。必要に応じて改行を除去または可視化します。

C#
string safeValue = input
.Replace("\r", "\\r")
.Replace("\n", "\\n");

7. 複数行の文字列を効率よく作る方法

7-1. +演算子で改行を連結する方法

少数の固定文字列を連結するだけなら、+演算子を使えます。

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

\nを使う場合は、次のように記述できます。

C#
string message =
"1行目\n" +
"2行目\n" +
"3行目";

固定された少数の文字列については、コンパイラによって効率よく処理されることがあります。

一方、ループ内で何度も文字列を追加すると、そのたびに新しい文字列が作成されるため、効率が低下する可能性があります。

C#
string result = "";

for (int i = 0; i < 10000; i++)
{
result += i + Environment.NewLine;
}

大量の文字列を繰り返し連結する場合は、StringBuilderが適しています。

7-2. StringBuilderで改行を追加する方法

StringBuilderは、文字列を繰り返し追加するときに便利なクラスです。

C#
using System.Text;

var builder = new StringBuilder();

builder.Append("1行目");
builder.Append(Environment.NewLine);
builder.Append("2行目");

string result = builder.ToString();

ループ内で複数行を作る例は次のとおりです。

C#
var builder = new StringBuilder();

for (int i = 1; i <= 5; i++)
{
builder.Append("項目");
builder.Append(i);
builder.Append(Environment.NewLine);
}

string result = builder.ToString();
Console.Write(result);

ただし、改行を追加するだけなら、AppendEnvironment.NewLineを別々に呼ぶより、AppendLineを使うほうが簡潔です。

7-3. AppendLineを使う方法

StringBuilder.AppendLineは、文字列を追加した後に改行を追加します。

C#
var builder = new StringBuilder();

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

string result = builder.ToString();

引数なしで呼び出すと、空行を追加できます。

C#
builder.AppendLine("見出し");
builder.AppendLine();
builder.AppendLine("本文");

AppendLineは通常、実行環境に応じた改行を追加します。

末尾に改行を含めたくない場合は、最後の行だけAppendを使います。

C#
var builder = new StringBuilder();

builder.AppendLine("1行目");
builder.AppendLine("2行目");
builder.Append("3行目");

7-4. string.Joinで改行区切りの文字列を作る方法

複数の文字列を改行で結合する場合は、string.Joinが便利です。

C#
string[] lines =
{
"りんご",
"みかん",
"ぶどう"
};

string result = string.Join(Environment.NewLine, lines);

Console.WriteLine(result);

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

りんご
みかん
ぶどう

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

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

string.Joinでは、通常、末尾に改行が追加されません。「各要素の間だけ改行したい」という場合に適しています。

7-5. 配列やリストを改行区切りで出力する方法

配列やリストを1行ずつ表示するだけなら、foreachConsole.WriteLineを使えます。

C#
var names = new List<string>
{
"山田",
"佐藤",
"鈴木"
};

foreach (string name in names)
{
Console.WriteLine(name);
}

1つの文字列に変換する場合は、string.Joinを使います。

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

オブジェクトの特定プロパティを改行区切りにする場合は、LINQと組み合わせます。

C#
var users = new[]
{
new { Name = "山田", Age = 30 },
new { Name = "佐藤", Age = 25 }
};

string text = string.Join(
Environment.NewLine,
users.Select(user => $"{user.Name}:{user.Age}歳")
);

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

山田:30歳
佐藤:25歳

8. 改行を置換・削除・分割する方法

8-1. 改行コードを別の文字に置換する方法

string.Replaceを使うと、改行を任意の文字へ置換できます。

C#
string text = "A\nB\nC";
string replaced = text.Replace("\n", ", ");

Console.WriteLine(replaced);

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

A, B, C

実行OSの改行コードを置換する場合は、Environment.NewLineを指定します。

C#
string replaced = text.Replace(Environment.NewLine, " / ");

ただし、外部から受け取った文字列には、\r\n\n\rが混在している可能性があります。その場合は、先に改行コードを統一します。

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

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

\r\nを先に置換することがポイントです。\rを先に処理すると、CRLFを正しく1つの改行として扱えない場合があります。

8-2. 改行を削除する方法

改行を完全に削除する場合は、空文字列へ置換します。

C#
string text = "A\r\nB\nC\rD";

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

Console.WriteLine(result);

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

ABCD

単語や文章が連結されるのを避けたい場合は、空白へ置換します。

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

連続する改行を1つの空白へまとめたい場合は、正規表現も利用できます。

C#
using System.Text.RegularExpressions;

string result = Regex.Replace(text, @"\r\n|\r|\n", " ");

8-3. 改行ごとに文字列を分割する方法

改行で文字列を分割するには、Splitを使います。

LFだけを対象にする場合は、次のように記述できます。

C#
string text = "A\nB\nC";
string[] lines = text.Split('\n');

OS標準の改行文字列で分割する場合は、次のようにします。

C#
string[] lines = text.Split(
new[] { Environment.NewLine },
StringSplitOptions.None
);

複数の改行形式へ対応する場合は、CRLFとLFとCRをすべて指定します。

C#
string[] lines = text.Split(
new[] { "\r\n", "\n", "\r" },
StringSplitOptions.None
);

空行を除外したい場合は、StringSplitOptions.RemoveEmptyEntriesを指定します。

C#
string[] lines = text.Split(
new[] { "\r\n", "\n", "\r" },
StringSplitOptions.RemoveEmptyEntries
);

行の前後にある空白も削除したい場合は、TrimEntriesを組み合わせられます。

C#
string[] lines = text.Split(
new[] { "\r\n", "\n", "\r" },
StringSplitOptions.RemoveEmptyEntries |
StringSplitOptions.TrimEntries
);

8-4. \r\nと\nが混在する文字列への対応

外部ファイル、Web API、コピー&ペーストされた文章などには、複数の改行コードが混在している場合があります。

安全に処理するには、まずすべての改行をLFへ統一します。

C#
static string NormalizeNewLines(string value)
{
return value
.Replace("\r\n", "\n")
.Replace("\r", "\n");
}

OS標準の改行へ統一したい場合は、LFへ正規化した後でEnvironment.NewLineへ置換します。

C#
static string NormalizeToPlatformNewLine(string value)
{
string normalized = value
.Replace("\r\n", "\n")
.Replace("\r", "\n");

return normalized.Replace("\n", Environment.NewLine);
}

この順序なら、WindowsでEnvironment.NewLine\r\nの場合でも、既存のCRLFを重複させずに変換できます。

8-5. 正規表現で改行を扱う方法

正規表現では、\r\n\r\nをまとめて扱えます。

C#
using System.Text.RegularExpressions;

string[] lines = Regex.Split(text, @"\r\n|\r|\n");

.NETの正規表現では、\r?\nを使ってCRLFまたはLFに対応する方法もあります。

C#
string[] lines = Regex.Split(text, @"\r?\n");

ただし、このパターンはCR単体を対象にしません。CR単体も処理する必要がある場合は、次のパターンを使います。

C#
string[] lines = Regex.Split(text, @"\r\n|\r|\n");

連続する複数の改行を1つへまとめる例は次のとおりです。

C#
string result = Regex.Replace(
text,
@"(?:\r\n|\r|\n)+",
Environment.NewLine
);

単純な置換や分割で済む場合はReplaceSplitのほうが読みやすく、複雑な改行パターンを処理する場合は正規表現が便利です。

9. C#の改行でよくあるエラーと対処法

9-1. \nがそのまま表示される原因

\nが改行されず、そのまま画面に表示される主な原因は、逐語的文字列リテラルを使っていることです。

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

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

1行目\n2行目

@を外すと、\nが改行として解釈されます。

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

逐語的文字列リテラルを使いたい場合は、ソースコード上で実際に改行します。

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

また、外部から受け取った文字列に、バックスラッシュとnの2文字が含まれている場合もあります。

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

実際の改行へ変換する場合は、置換します。

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

ただし、JSONなどの形式から読み込む場合は、自前で置換するより、適切なデシリアライザーを使うほうが安全です。

9-2. 改行されない原因

改行されない場合は、出力先が改行コードを表示上の改行として扱っているか確認します。

代表的な原因は次のとおりです。

  • HTMLへ\nを出力している

  • WinFormsのTextBox.Multilinefalse

  • WPFで改行入力に必要な設定が不足している

  • 文字列に実際の改行ではなく\\nが入っている

  • 出力先が特定の改行コードしか受け付けない

  • CSSによって改行や空白が折りたたまれている

文字列に何が含まれているか確認するには、改行を見える形式へ置換すると分かりやすくなります。

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

Console.WriteLine(visible);

たとえば、CRLFが含まれていれば、次のように表示されます。

1行目\r\n2行目

9-3. テキストボックスで改行が反映されない原因

WinFormsのTextBoxで改行が反映されない場合は、Multilineが無効になっている可能性があります。

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

入力欄の高さが1行分しかない場合も、複数行が見えにくくなります。コントロールの高さやスクロールバーも確認します。

C#
textBox1.ScrollBars = ScrollBars.Vertical;

WPFでは、Enterキーで改行入力させる場合にAcceptsReturn="True"を設定します。

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

表示だけであれば文字列内の改行が反映されますが、入力操作まで考慮する場合はコントロール固有の設定が必要です。

9-4. ファイル出力後に改行が崩れる原因

ファイル出力後に改行が崩れる場合は、出力した改行コードと、読み込むソフトウェアが想定する改行コードが一致していない可能性があります。

たとえば、連携先がCRLFを要求している場合は、明示的に\r\nを使います。

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

StreamWriterでは、NewLineプロパティを設定できます。

C#
using var writer = new StreamWriter("output.txt");
writer.NewLine = "\r\n";

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

LFを要求するシステムなら、次のようにします。

C#
writer.NewLine = "\n";

文字コードの問題が改行の崩れに見える場合もあります。UTF-8など、ファイルを利用するシステムが要求するエンコーディングも併せて確認します。

9-5. OSやエディタによって表示が違う場合の対処法

OSやエディタによる差を減らすには、プロジェクト内で改行コードのルールを決めます。

たとえば、ソースコードと設定ファイルはLF、Windows向けの出力ファイルはCRLFというように、用途ごとに統一します。

入力データについては、読み込み時に改行コードを正規化すると扱いやすくなります。

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

出力時には、必要な形式へ変換します。

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

Gitを使用している場合は、.gitattributesで改行コードを管理する方法もあります。

* text=auto
*.cs text eol=lf
*.bat text eol=crlf

外部システムへ渡すファイルでは、「OS標準」ではなく、そのシステムの仕様に合わせて改行コードを固定することが重要です。

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

10-1. \nと\r\nはどちらを使えばよいか

用途によって使い分けます。

プログラム内部の文字列、Web関連のデータ、Linux環境、LFへ統一されたプロジェクトでは、\nが扱いやすい選択肢です。

Windows形式のテキストファイルや、CRLFを要求する外部システムへ出力する場合は、\r\nを使います。

実行中のOSに適した形式で出力したい場合は、Environment.NewLineを使います。

C#
string text = $"1行目{Environment.NewLine}2行目";

外部仕様がある場合は、その仕様を最優先します。

10-2. Console.WriteLineと\nの違いは何か

\nは、文字列内に含める改行文字です。

C#
string text = "A\nB";

Console.WriteLineは、指定された値をコンソールへ出力し、最後に改行するメソッドです。

C#
Console.WriteLine("A");
Console.WriteLine("B");

次のコードでは、文字列内の\nと、WriteLineによる末尾の改行の両方が使われます。

C#
Console.WriteLine("A\nB");

つまり、\nは文字列の構成要素、Console.WriteLineは出力処理です。

10-3. Environment.NewLineは必ず使うべきか

必ず使う必要はありません。

Environment.NewLineは、現在の実行環境に適した改行コードを使いたい場合に便利です。しかし、データ形式としてLFが指定されている場合に使うと、Windows上ではCRLFになり、仕様と異なる結果になる可能性があります。

次のように使い分けます。

C#
// LFへ固定
string data = "A\nB";

// 実行環境に合わせる
string displayText = $"A{Environment.NewLine}B";

// Windows形式へ固定
string windowsText = "A\r\nB";

「どこで動かすか」だけでなく、「その文字列を誰が、どの仕様で読むか」を基準に選ぶことが大切です。

10-4. 改行コードを統一するにはどうすればよいか

まず、すべての改行コードをLFへ正規化します。

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

LFへ統一する場合は、この状態をそのまま利用します。

C#
File.WriteAllText("output.txt", normalized);

CRLFへ統一する場合は、正規化後に置換します。

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

実行環境の改行へ統一する場合は、Environment.NewLineへ置換します。

C#
string platformText =
normalized.Replace("\n", Environment.NewLine);

最初にCRLFをLFへ変換してから処理することで、\r\r\nのような不正な重複を防げます。

10-5. C#でおすすめの改行方法はどれか

一般的には、用途ごとに次の方法がおすすめです。

短い文字列の途中で改行する場合は、\nが簡単です。

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

実行環境に合ったテキストを作る場合は、Environment.NewLineを使います。

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

固定された複数行の文章には、Raw文字列リテラルが読みやすくなります。

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

大量の行を動的に作る場合は、StringBuilder.AppendLineが適しています。

C#
var builder = new StringBuilder();
builder.AppendLine("1行目");
builder.AppendLine("2行目");

配列やリストを改行で結合する場合は、string.Joinが簡潔です。

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

外部ファイルやAPIなどに出力する場合は、便利さだけで選ばず、相手側が要求する改行コードを確認してください。

まとめ

C#で改行する最も基本的な方法は、文字列内に\nを含めることです。

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

実行中のOSに適した改行コードを使う場合は、Environment.NewLineを利用します。

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

Windowsでは一般的にCRLF(\r\n)、Linuxと現在のmacOSでは一般的にLF(\n)が使われます。ただし、外部システムやデータ形式に明確な指定がある場合は、OSではなく仕様に合わせなければなりません。

複数行の固定文章には逐語的文字列リテラルやRaw文字列リテラル、大量の行を動的に組み立てる場合にはStringBuilder.AppendLine、配列やリストを結合する場合にはstring.Joinが便利です。

また、外部から取得した文字列を処理するときは、CRLF、LF、CRが混在している可能性を考慮します。

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

C#の改行では、「画面に表示するだけなのか」「ファイルへ保存するのか」「外部システムへ渡すのか」によって適切な方法が変わります。出力先の仕様を確認したうえで、\n\r\nEnvironment.NewLineを使い分けましょう。