C#のConsole.WriteLineの使い方:コンソールに文字列や変数の値を表示する方法【サンプルコード付き】

C#で最初に出会うI/Oがコンソール出力です。

中でもConsole.WriteLineは、文字列や数値、日時、オブジェクトなどを見やすく表示するための基本メソッドです。

本記事では、基本から書式指定、ローカライズ、エラー出力、実用サンプル、注意点・ベストプラクティスまで丁寧に解説します。

Console.WriteLineとは?

役割と基本概念

Console.WriteLineは標準出力(Standard Output)へ内容を表示し、行末に改行を追加するメソッドです。

改行は環境依存のEnvironment.NewLine(WindowsはCRLF、Unix系はLF)で表されます。

引数には文字列だけでなく、数値、ブール値、日時、任意のオブジェクトを渡せます。

オーバーロードの概略

Console.WriteLineには多くのオーバーロードがあります。

代表的なものは以下です。

  • WriteLine()(空行)
  • WriteLine(string value)
  • WriteLine(object value)ToString()で文字列化)
  • WriteLine(string format, params object?[] args)(複合書式)
  • WriteLine(ReadOnlySpan<char> value)などの効率的なオーバーロード

バッファとフラッシュ

コンソールはバッファリングされることがあり、改行付き出力は区切りとして扱われるため、行単位で出力が見やすくなります。

必要に応じてConsole.Out.Flush()で明示的にフラッシュできます。

Console.WriteLineの基本的な使い方

文字列を表示する

最も基本的な使い方は文字列をそのまま表示することです。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        // 単純な文字列の表示
        Console.WriteLine("Hello, Console!");

        // 空行の出力
        Console.WriteLine();

        // 日本語や記号の表示(文字化けする場合は後述のOutputEncodingを参照)
        Console.WriteLine("こんにちは、世界!★");
    }
}

実行結果例

実行結果
Hello, Console!

こんにちは、世界!★

変数・数値・ブール値を表示する

変数はそのまま渡せます。

オブジェクトはToString()が呼ばれます。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        int count = 3;
        double price = 1234.5;
        bool isActive = true;

        Console.WriteLine(count);    // 数値
        Console.WriteLine(price);    // 小数
        Console.WriteLine(isActive); // ブール値

        object any = new Version(1, 2, 3, 4);
        Console.WriteLine(any);      // object → ToString()が呼ばれる
    }
}

実行結果例

実行結果
3
1234.5
True
1.2.3.4

文字列連結と改行の扱い

文字列は+演算子で連結できますが、読みやすさやパフォーマンスの観点からは文字列補間や書式指定を推奨します。

改行には\nEnvironment.NewLineを使えます。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        string first = "Alice";
        string last = "Smith";

        // 連結
        Console.WriteLine("Name: " + first + " " + last);

        // 改行(環境依存で安全な方法)
        Console.WriteLine("Line1" + Environment.NewLine + "Line2");

        // エスケープ(\n, \t, \\ など)
        Console.WriteLine("Path: C:\\tools\\app.exe\t<- ここにあります");
    }
}

実行結果例

実行結果
Name: Alice Smith
Line1
Line2
Path: C:\tools\app.exe	<- ここにあります

Console.WriteとConsole.WriteLineの違い

Console.Writeは改行なし、Console.WriteLineは改行ありです。

連続出力の区切りに注意します。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        Console.Write("A");
        Console.Write("B");
        Console.Write("C");
        Console.WriteLine(); // ここで改行
        Console.WriteLine("D"); // 最後に改行込み
    }
}

実行結果例

実行結果
ABC
D

文字列補間と書式指定で見やすく表示する

文字列補間$””で変数値を埋め込む

$"..."を用いると、変数や式を{}内に直接書け、可読性が高まります。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        string user = "Alice";
        int age = 28;
        Console.WriteLine($"User: {user}, Age: {age}");

        // 式もOK
        Console.WriteLine($"Next year: {age + 1}");
    }
}

実行結果例

実行結果
User: Alice, Age: 28
Next year: 29

複合書式{0}とstring.Formatの使い方

古典的な複合書式は、テンプレートと引数の位置指定で整列や桁数指定が行えます。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        string item = "Notebook";
        int qty = 12;
        double price = 1234.5;

        Console.WriteLine("Item: {0}, Qty: {1}, Price: {2}", item, qty, price);

        // 整列(左詰め-10、右詰め10)
        Console.WriteLine("|{0,-10}|{1,10}|", item, qty);

        // string.Formatで一旦文字列化してから出力
        string line = string.Format("合計: {0}", qty * price);
        Console.WriteLine(line);
    }
}

実行結果例

実行結果
Item: Notebook, Qty: 12, Price: 1234.5
|Notebook  |        12|
合計: 14814

数値フォーマット(小数・通貨・パーセント)

数値は書式指定文字列で見やすく整形できます。

既定カルチャの影響を受けます(後述のCultureInfoで制御可能)。

サンプルコード

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        double value = 12345.6789;

        Console.WriteLine($"F2(小数2桁): {value:F2}");
        Console.WriteLine($"N0(桁区切り): {value:N0}");
        Console.WriteLine($"C(通貨): {value:C}");
        Console.WriteLine($"P(パーセント): {0.256:P1}"); // 25.6%
        Console.WriteLine($"カスタム('#,0.00'): {value:#,0.00}");

        // CultureInfoを指定して通貨の記号や桁区切りを切り替え
        var ja = new CultureInfo("ja-JP");
        var us = new CultureInfo("en-US");
        Console.WriteLine($"ja-JP通貨: {value.ToString("C", ja)}");
        Console.WriteLine($"en-US通貨: {value.ToString("C", us)}");
    }
}

実行結果例

実行結果
F2(小数2桁): 12345.68
N0(桁区切り): 12,346
C(通貨): ¥12,345.68
P(パーセント): 25.6 %
カスタム('#,0.00'): 12,345.68
ja-JP通貨: ¥12,345.68
en-US通貨: $12,345.68

日付・時刻のフォーマット(DateTime/TimeSpan)

日時や時間間隔も書式指定で自在に表現できます。

サンプルコード

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        var dt = new DateTime(2025, 5, 1, 14, 30, 5, DateTimeKind.Local);
        var ts = new TimeSpan(1, 2, 3, 4, 567); // 1日2時間3分4秒567ms

        // 標準書式
        Console.WriteLine($"短い日時(g): {dt:g}");
        Console.WriteLine($"長い日時(F): {dt:F}");
        Console.WriteLine($"ISOっぽい(o): {dt:o}");
        Console.WriteLine($"RFC1123(R): {dt:R}");

        // カスタム書式
        Console.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss"));
        Console.WriteLine(ts.ToString(@"d\.hh\:mm\:ss\.fff"));

        // CultureInfoで曜日名・月名などをローカライズ
        var us = new CultureInfo("en-US");
        Console.WriteLine(dt.ToString("dddd, MMMM dd, yyyy", us));
    }
}

実行結果例

実行結果
短い日時(g): 2025/05/01 14:30
長い日時(F): 2025年5月1日 14:30:05
ISOっぽい(o): 2025-05-01T14:30:05.0000000+09:00
RFC1123(R): Thu, 01 May 2025 05:30:05 GMT
2025-05-01 14:30:05
1.02:03:04.567
Thursday, May 01, 2025

出力を整える実用テクニック

複数行出力・タブ・エスケープシーケンス

行の区切りやインデントには改行やタブを使います。

複数行のリテラルには逐語的文字列(@)も便利です。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Header\tColumn1\tColumn2");
        Console.WriteLine("Data\t100\t200");

        // 複数行(逐語的文字列: バックスラッシュや改行をそのまま)
        Console.WriteLine(@"C:\logs\app.log
C:\logs\error.log");

        // 環境依存しない改行
        Console.WriteLine("LineA" + Environment.NewLine + "LineB");
    }
}

実行結果例

実行結果
Header	Column1	Column2
Data	100	200
C:\logs\app.log
C:\logs\error.log
LineA
LineB

CultureInfoでローカライズ表示

数値や日時の既定フォーマットは「現在カルチャ」に依存します。

CultureInfo.CurrentCultureや明示指定で制御します。

サンプルコード

C#
using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        double n = 12345.67;
        DateTime d = new(2025, 8, 1);

        var fr = new CultureInfo("fr-FR");
        var ja = new CultureInfo("ja-JP");

        Console.WriteLine(n.ToString("N2", fr)); // 12 345,67
        Console.WriteLine(d.ToString("D", ja));  // 2025年8月1日
    }
}

Console.OutputEncodingで文字化け対策

Windowsの既定コードページでは日本語や絵文字が文字化けすることがあります。

UTF-8を明示しましょう。

サンプルコード

C#
using System;
using System.Text;

class Program
{
    static void Main()
    {
        // UTF-8に設定(BOMなし)
        Console.OutputEncoding = new UTF8Encoding(false);

        Console.WriteLine("日本語と絵文字😊の表示テスト");
    }
}
実行結果
日本語と絵文字😊の表示テスト

注意

  • 端末側がUTF-8に対応している必要があります。Windowsの旧コンソールではchcp 65001や「ベータ: Unicode UTF-8を使用」に設定が必要な場合があります。
  • 出力をファイルへリダイレクトする場合も、意図したエンコーディングで保存されます。

Console.Error.WriteLineでエラー出力を分ける

標準エラー(Standard Error)に出力すると、通常ログとエラーを別ストリームで扱えます。

リダイレクト時にも分離可能です。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Info: アプリ開始");
        Console.Error.WriteLine("Error: 予期せぬエラーが発生しました");
    }
}

実行方法の例

  • 標準出力をファイル、標準エラーを画面に残す(PowerShell):
    • dotnet run > out.txt
  • 標準エラーも別ファイルへ(PowerShell):
    • dotnet run 1> out.txt 2> err.txt

実用サンプルコード集

ループでのログ出力とインデント

処理の階層に応じてインデントを付けると読みやすくなります。

サンプルコード

C#
using System;

class Program
{
    static void Log(string message, int indent = 0)
    {
        // インデント幅は2スペース×レベル
        string pad = new string(' ', indent * 2);
        Console.WriteLine($"{pad}{message}");
    }

    static void Main()
    {
        Log("Start");
        for (int i = 0; i < 3; i++)
        {
            Log($"Loop i={i}", 1);
            for (int j = 0; j < 2; j++)
            {
                Log($"Inner j={j}", 2);
            }
        }
        Log("Done");
    }
}

実行結果例

実行結果
Start
  Loop i=0
    Inner j=0
    Inner j=1
  Loop i=1
    Inner j=0
    Inner j=1
  Loop i=2
    Inner j=0
    Inner j=1
Done

例外メッセージとスタックトレースを表示

例外情報はException.ToString()でメッセージとスタックトレースをまとめて取得できます。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        try
        {
            ThrowNested();
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine("=== 例外発生 ===");
            // 例外メッセージ
            Console.Error.WriteLine(ex.Message);
            // スタックトレース
            Console.Error.WriteLine(ex.StackTrace);
            // まとめて(型, メッセージ, スタック, InnerExceptionまで含む)
            Console.Error.WriteLine("--- ex.ToString() ---");
            Console.Error.WriteLine(ex.ToString());
        }
    }

    static void ThrowNested()
    {
        try
        {
            int x = int.Parse("not-an-int");
        }
        catch (FormatException fe)
        {
            throw new InvalidOperationException("パースに失敗しました。", fe);
        }
    }
}

実行結果例(抜粋)

実行結果
=== 例外発生 ===
パースに失敗しました。
(スタックトレースが表示)
--- ex.ToString() ---
System.InvalidOperationException: パースに失敗しました。 ---> System.FormatException: Input string was not in a correct format.
   at ...

オブジェクトの表示(ToStringとJSONシリアライズ)

ToString()のオーバーライドで簡易表示、詳細はJSONで整形すると便利です。

サンプルコード

C#
using System;
using System.Text.Json;

class User
{
    public string Name { get; init; } = "";
    public int Age { get; init; }

    // ログ向けの簡易表現
    public override string ToString() => $"{Name}({Age})";
}

class Program
{
    static void Main()
    {
        var user = new User { Name = "Alice", Age = 30 };
        Console.WriteLine(user); // ToString()

        // JSONで詳細表示(インデント有り)
        var json = JsonSerializer.Serialize(user, new JsonSerializerOptions
        {
            WriteIndented = true
        });
        Console.WriteLine(json);
    }
}

実行結果例

実行結果
Alice(30)
{
  "Name": "Alice",
  "Age": 30
}

書式付きテーブル風の出力

列幅と整列指定でテーブル風に整えます。

サンプルコード

C#
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var rows = new List<(string Name, int Qty, double Price)>
        {
            ("Notebook", 3, 1200.0),
            ("Pencil", 12, 80.5),
            ("Eraser", 2, 50),
        };

        Console.WriteLine("| {0,-10} | {1,5} | {2,10} | {3,12} |", "Item", "Qty", "Price", "Subtotal");
        Console.WriteLine(new string('-', 52));

        foreach (var r in rows)
        {
            double subtotal = r.Qty * r.Price;
            Console.WriteLine("| {0,-10} | {1,5} | {2,10:F2} | {3,12:N2} |",
                r.Name, r.Qty, r.Price, subtotal);
        }
    }
}

実行結果例

実行結果
| Item       |   Qty |      Price |     Subtotal |
----------------------------------------------------
| Notebook   |     3 |    1200.00 |     3,600.00 |
| Pencil     |    12 |      80.50 |       966.00 |
| Eraser     |     2 |      50.00 |       100.00 |

よくあるエラー・注意点とベストプラクティス

null/Nullableの表示と安全な扱い

文字列連結や補間にnullを含むと、補間では空文字列、連結では"文字列" + nullがそのまま"文字列"になりますが、null.ToString()は例外になります。

?.??演算子で安全に表示しましょう。

サンプルコード

C#
using System;

class Program
{
    static void Main()
    {
        string? s = null;

        // OK: nullは空として扱われる
        Console.WriteLine($"value='{s}'"); // value=''

        // 安全なフォールバック
        Console.WriteLine($"value='{s ?? "(null)"}'");

        // NG: 直接ToString()は例外
        // Console.WriteLine(s.ToString()); // NullReferenceException

        // オブジェクトでも同様
        object? o = null;
        Console.WriteLine($"{o?.ToString() ?? "(null object)"}");
    }
}

パフォーマンス(連結 vs 補間 vs StringBuilder)

コンソール出力自体が比較的高コストなI/Oのため、単発の出力では連結方法の差は体感しにくいです。

加工が複雑・繰り返し文字列構築が多い場合はStringBuilderが有利です。

ただし、文字列補間($)は可読性が高く、内部的に効率化されることも多いため、まずは補間を使い、ボトルネック時にStringBuilderを検討します。

例:大量結合はStringBuilder

C#
using System;
using System.Text;

class Program
{
    static void Main()
    {
        var sb = new StringBuilder();
        for (int i = 0; i < 5_000; i++)
        {
            sb.Append("Line ").Append(i).Append('\n');
        }
        Console.WriteLine(sb.ToString());
    }
}

出力のリダイレクトとバッファリングの注意

>2>でリダイレクトすると、出力はファイルや他プロセスへ流れます。このときConsole.IsOutputRedirectedConsole.IsErrorRedirectedtrueになります。

リダイレクト先によってはバッファリングされ、出力がすぐ見えない場合があります。必要に応じてConsole.Out.Flush()AutoFlushを使います。

明示的にファイルへ切り替える場合はConsole.SetOutを利用します。

サンプルコード(UTF-8でファイルへ)

C#
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main()
    {
        using var writer = new StreamWriter("log.txt", append: false, new UTF8Encoding(false))
        {
            AutoFlush = true
        };
        Console.SetOut(writer);

        Console.WriteLine("ファイルに書き込まれます");
        Console.Out.Flush(); // 念のため
    }
}

非同期コード・並列実行時のConsole出力の衝突対策

複数スレッドやasync/awaitで同時に出力すると、行が混ざることがあります。

1回のWriteLineで1行を完成させ、分割書き込みを避ける。

共有ロックで同期する、あるいは専用スレッドにログをキューイングする。

Console.Outはスレッドセーフですが、複数行に跨る書き込みは混在し得ます。

サンプルコード(ロックで保護)

C#
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static readonly object _lock = new();

    static async Task Main()
    {
        var t1 = Task.Run(() => LogMany("A"));
        var t2 = Task.Run(() => LogMany("B"));
        await Task.WhenAll(t1, t2);
    }

    static void LogMany(string tag)
    {
        for (int i = 0; i < 5; i++)
        {
            string line = $"{tag}: message {i}";
            lock (_lock) // 1行単位で同期
            {
                Console.WriteLine(line);
            }
            Thread.Sleep(10);
        }
    }
}

サンプルコード(非同期書き込み)

C#
using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // Console.Out.WriteLineAsyncはTextWriterの非同期API
        await Console.Out.WriteLineAsync("Async line 1");
        await Console.Out.WriteLineAsync("Async line 2");
    }
}

まとめ

Console.WriteLineはC#における基本的かつ強力な出力手段です。

単純な文字列表示から、補間・書式指定による整形、数値や日時のローカライズ、エンコーディングの指定、エラー出力の分離まで、利用範囲は広く実務でも頻出します。

まずは読みやすさを優先して文字列補間を活用し、必要に応じて複合書式やCultureInfoConsole.OutputEncodingを使い分けましょう。

並列・非同期での出力は1行単位の同期やキューイングで混在を避け、リダイレクトやファイル出力ではエンコーディングとバッファリングに注意することが大切です。

これらのコツを押さえれば、開発中のデバッグや運用ログが一段と読みやすく、役立つものになります。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!