コンソールアプリでユーザーからテキストを受け取る最も基本的な方法がConsole.ReadLineです。
Enterで確定する行単位の入力、戻り値の型とnullの扱い、EOFの意味、繰り返し入力のパターン、ブロッキング動作の注意点までを、初心者の方でも段階的に理解できるように解説します。
C#のConsole.ReadLineの基本と使い方
Console.ReadLineとは
Console.ReadLineは、標準入力から1行の文字列を読み取るメソッドです。
ユーザーがキーボードで入力し、Enterを押すまでプログラムは待機します。
その後、入力された1行分の文字列が戻り値として返ります。
返される文字列には改行文字は含まれません。
また、入力が終端(EOF)に達した場合はnullが返ります。
C#のNullable参照型が有効なプロジェクトでは、戻り値の型はstring?になります。
最小のサンプルコード
// Console.ReadLineの最小例
// ユーザーの入力を1行読み取り、そのまま表示します。
using System;
class Program
{
static void Main()
{
Console.Write("何か入力してください: "); // プロンプトを表示
string? line = Console.ReadLine(); // Enterで確定するまで待機
if (line is null) // EOFの場合はnull
{
Console.WriteLine("入力が終了しました(EOF)。");
return;
}
Console.WriteLine($"あなたが入力したのは「{line}」です。");
}
}
何か入力してください: Hello
あなたが入力したのは「Hello」です。
キーボード入力の流れ(Enterで確定)
キーボードからの入力は、ユーザーが文字をタイプし、Enterを押すと1行として確定します。
この時点でConsole.ReadLineは待機状態を抜け、確定した行を返します。
行末の改行コードは取り除かれるため、返される文字列に改行は含まれません。
次の例は、ReadLineがどのタイミングで処理をブロックするかを目で確認するためのものです。
// ReadLineのブロッキング動作を確認する例
using System;
class Program
{
static void Main()
{
Console.WriteLine("A: これが最初に表示されます。");
string? line = Console.ReadLine(); // ここでEnterが押されるまで停止
Console.WriteLine("B: 入力確定後に表示されます。");
}
}
A: これが最初に表示されます。
test ← ここでユーザーが入力してEnter
B: 入力確定後に表示されます。
プロンプトを表示して入力を促す
ユーザーに何を入力すればよいか明示するために、Console.Writeで同一行にプロンプトを表示してからConsole.ReadLineを呼び出すのが一般的です。
Console.WriteLineを使うとプロンプトの後ろで改行されるため、入力欄が次行になります。
状況に応じて使い分けます。
// プロンプト付きの入力例
using System;
class Program
{
static void Main()
{
Console.Write("あなたの名前を入力してください: "); // 同じ行に入力してほしいのでWriteを使う
string? name = Console.ReadLine();
if (name is null)
{
Console.WriteLine("入力が終了しました(EOF)。");
return;
}
Console.WriteLine($"こんにちは、{name}さん!");
}
}
あなたの名前を入力してください: Taro
こんにちは、Taroさん!
Console.ReadLineの戻り値と入力の扱い
stringで受け取る(改行は含まない)
Console.ReadLineの戻り値は文字列で、行末の改行を含みません。
打鍵した文字数と戻り値のLengthが一致することを簡単に確認できます。
// 改行が含まれないことを確認する例
using System;
class Program
{
static void Main()
{
Console.Write("文字を入力してください: ");
string? s = Console.ReadLine();
if (s is null)
{
Console.WriteLine("EOFです。");
return;
}
Console.WriteLine($"入力文字数は{s.Length}です。"); // 改行は含まれない
}
}
文字を入力してください: abc
入力文字数は3です。
空行の判定と処理
ユーザーが何も入力せずにEnterだけ押すと、空文字列(“”)が返ります。
この場合は空行として扱い、スキップしたり、再入力を促したりします。
空白のみの行もまとめて無視したい場合はstring.IsNullOrWhiteSpaceを使うと便利です。
// 空行や空白行を判定して処理を分岐する例
using System;
class Program
{
static void Main()
{
Console.Write("年齢を入力してください(空行でスキップ): ");
string? input = Console.ReadLine();
if (input is null)
{
Console.WriteLine("EOFが検出されました。");
return;
}
if (string.IsNullOrWhiteSpace(input)) // 空文字または空白のみ
{
Console.WriteLine("空行が入力されました。スキップします。");
}
else
{
Console.WriteLine($"入力された文字列: {input}");
}
}
}
年齢を入力してください(空行でスキップ):
空行が入力されました。スキップします。
EOF時はnullになる(Ctrl+Z/Ctrl+D)
入力が終端に達した場合、Console.ReadLineはnullを返します。
これはファイルやパイプからの入力を読み切ったときや、ユーザーが手動でEOFを送ったときに発生します。
EOFの出し方はOSによって異なります。
下表は代表的な操作です。
OS | EOFの出し方 | 備考 |
---|---|---|
Windows(コンソール) | Ctrl+Z の後にEnter | Ctrl+Zだけでは確定されないためEnterが必要 |
Linux/macOS(ターミナル) | Ctrl+D | 入力行が空のときにEOFを送るのが一般的 |
EOFを正しく扱うには、nullかどうかを判定します。
// EOF(null)まで行を読み続ける例
using System;
class Program
{
static void Main()
{
Console.WriteLine("行を入力してください。EOFで終了します。");
string? line;
while ((line = Console.ReadLine()) is not null) // nullならループ終了
{
Console.WriteLine($"受信: {line}");
}
Console.WriteLine("EOFです。終了します。");
}
}
行を入力してください。EOFで終了します。
apple
受信: apple
banana
受信: banana
Ctrl+Z → Enter(Windows) もしくは Ctrl+D(Linux/macOS)
EOFです。終了します。
Console.ReadLineの反復入力パターン
whileで複数行を読む
複数行を処理したい場合、whileループでConsole.ReadLineを繰り返し呼び出すのが基本です。
EOFでnullになったらループを抜けるようにします。
// 複数行を読み取って逐次処理する基本パターン
using System;
class Program
{
static void Main()
{
Console.WriteLine("1行ずつ入力してください。EOFで終了します。");
string? line;
while ((line = Console.ReadLine()) is not null)
{
// ここでlineを処理する
Console.WriteLine($"echo> {line}");
}
Console.WriteLine("入力が終了しました。");
}
}
1行ずつ入力してください。EOFで終了します。
hello
echo> hello
world
echo> world
Ctrl+Z → Enter(Windows) または Ctrl+D(Linux/macOS)
入力が終了しました。
終了コマンド(exit)でループを抜ける
ユーザーが特定のキーワードを入力したら終了する、という対話的なパターンもよく使われます。
EOFとコマンドのどちらでも終了できるようにしておくと親切です。
// 'exit'で終了する対話ループ
using System;
class Program
{
static void Main()
{
Console.WriteLine("コマンドを入力してください。'exit'で終了、EOFでも終了します。");
while (true)
{
Console.Write("> "); // プロンプト
string? line = Console.ReadLine();
if (line is null) // EOF
{
Console.WriteLine("EOFを検出しました。終了します。");
break;
}
if (line.Equals("exit", StringComparison.OrdinalIgnoreCase)) // 大文字小文字を無視
{
Console.WriteLine("コマンドで終了します。");
break;
}
Console.WriteLine($"受け取りました: {line}");
}
}
}
コマンドを入力してください。'exit'で終了、EOFでも終了します。
> ping
受け取りました: ping
> EXIT
コマンドで終了します。
空行をスキップする
空行は処理のノイズになることが多いので、continueで簡単にスキップできます。
以下は入力された整数の合計を計算する例です。
空行はスキップし、”exit”またはEOFで終了します。
// 空行をスキップしながら整数を読み取って合計する例
using System;
class Program
{
static void Main()
{
Console.WriteLine("整数を1行に1つ入力してください。空行はスキップ、'exit'またはEOFで終了します。");
int sum = 0;
while (true)
{
Console.Write("> ");
string? line = Console.ReadLine();
if (line is null) // EOF
{
Console.WriteLine("EOF。計算を終了します。");
break;
}
if (string.Equals(line, "exit", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("exitコマンドで終了します。");
break;
}
if (string.IsNullOrWhiteSpace(line)) // 空行や空白行はスキップ
{
continue;
}
// 数値に変換できれば加算、できなければエラー表示
if (int.TryParse(line, out int value))
{
sum += value;
Console.WriteLine($"現在の合計: {sum}");
}
else
{
Console.WriteLine("整数を入力してください。例: 42");
}
}
Console.WriteLine($"最終合計: {sum}");
}
}
整数を1行に1つ入力してください。空行はスキップ、'exit'またはEOFで終了します。
> 10
現在の合計: 10
>
> 8
現在の合計: 18
> abc
整数を入力してください。例: 42
> exit
exitコマンドで終了します。
最終合計: 18
Console.ReadLineの注意点とベストプラクティス
ブロッキング動作に注意
Console.ReadLineはユーザーがEnterで行を確定するまで処理をブロックします。
この特性により、ReadLineの手前で表示したメッセージ以降の処理は、入力が行われるまで進みません。
コンソールアプリでは通常問題ありませんが、同時に他の処理を走らせたい場合は設計に注意します。
どうしても非同期で扱いたい場合は、別スレッドでReadLineを実行してTask.WhenAnyで待つなどの方法がありますが、初心者向けの範囲を超えるため、ここでは詳細に立ち入りません。
// ブロッキングの基本理解に役立つ短い例
using System;
class Program
{
static void Main()
{
Console.WriteLine("この下のReadLineで入力を待ちます。入力が確定するまで先へ進みません。");
_ = Console.ReadLine(); // ← ここで待つ
Console.WriteLine("入力が確定したので、ここまで進みました。");
}
}
この下のReadLineで入力を待ちます。入力が確定するまで先へ進みません。
test
入力が確定したので、ここまで進みました。
nullチェックとガード節
EOF時にnullが返るため、nullチェックは必須です。
処理の早い段階でガード節を置いて分岐を単純化すると読みやすくなります。
// nullガードで早期リターンする例
using System;
class Program
{
static void Main()
{
Console.Write("入力してください: ");
string? line = Console.ReadLine();
if (line is null) // EOFを最初に処理
{
Console.WriteLine("EOFです。処理を終了します。");
return;
}
// ここから下はlineが非nullであることが保証される
Console.WriteLine($"大文字に変換: {line.ToUpperInvariant()}");
}
}
入力してください: hello
大文字に変換: HELLO
リダイレクト入力時の挙動(EOFの考え方)
Console.ReadLineは、キーボードからの入力だけでなく、ファイルやパイプからのリダイレクト入力もそのまま扱えます。
この場合、ファイル末尾やパイプの終端がEOFになり、ReadLineはnullを返して終了します。
プロンプト表示は不要か、あっても邪魔にならないように最小限にします。
// 標準入力から受け取った行数を数える例
using System;
class Program
{
static void Main()
{
int count = 0;
string? line;
while ((line = Console.ReadLine()) is not null)
{
count++;
}
Console.WriteLine($"受け取った行数: {count}");
}
}
実行例(シェル)
- Windows PowerShell:
Get-Content input.txt | dotnet run
- Windows(コマンドプロンプト):
type input.txt | dotnet run
- Linux/macOS:
cat input.txt | dotnet run
受け取った行数: 5
なお、リダイレクト時はプログラム側からのプロンプトが大量に出ると、出力と入力の混在で分かりにくくなります。
バッチ処理を想定している場合はプロンプトを出さない、あるいはVerboseオプションを用意して切り替えるなどの工夫をすると実用的です。
まとめ
Console.ReadLineは、コンソールアプリでユーザー入力を扱ううえで最初に身につけたい基礎です。
Enterで確定される1行を読み取り、通常は文字列として返り、EOF時のみnullになることを理解しておくと、多くのケースで正しく対処できます。
反復入力ではwhileループとnullチェックが定番で、終了コマンドや空行スキップの仕組みを加えると実用性が高まります。
ブロッキング動作の特性を踏まえ、必要に応じて設計や表示を工夫すれば、対話的なツールからバッチ処理まで幅広く対応できます。