C#を使用したアプリケーション開発において、ユーザーからの入力を受け取る処理は、対話型のプログラムやコマンドラインツールを作成する上で最も基本的な要素の一つです。

特にコンソールアプリケーションでは、キーボードからの入力を取得し、それを適切なデータ型に変換して処理に利用する流れを正しく理解しておく必要があります。

本記事では、C#における標準入力の基本である Console.ReadLine メソッドの使い方から、数値への安全な変換方法、複数データの同時取得、さらには例外処理を含めた実践的なテクニックまで、初心者から中級者まで役立つ情報を詳しく解説します。

C#における標準入力の基本

C#でコンソールから入力を取得する際に最も頻繁に利用されるのが、System.Consoleクラスに用意されているReadLineメソッドです。

このメソッドは、ユーザーがキーボードで文字を入力し、エンターキーを押すまでの1行を文字列として取得します。

Console.ReadLineメソッドの仕組み

Console.ReadLineメソッドの最大の特徴は、「入力された内容を常に文字列 (string型) として受け取る」という点です。

たとえユーザーが数字の「100」を入力したとしても、プログラム内部では数値の100ではなく、文字列の “100” として扱われます。

以下に、最もシンプルな入力取得のコード例を示します。

C#
using System;

class Program
{
    static void Main()
    {
        // ユーザーにメッセージを表示
        Console.Write("あなたの名前を入力してください: ");

        // キーボードからの入力を取得
        string? input = Console.ReadLine();

        // 入力された内容を画面に表示
        Console.WriteLine("こんにちは、" + input + "さん!");
    }
}

実行結果の例

あなたの名前を入力してください: 太郎
こんにちは、太郎さん!

このプログラムでは、Console.ReadLine()が呼び出された時点でプログラムの実行が一時停止し、ユーザーの入力を待ちます。

ユーザーが文字を入力してエンターキーを押すと、その内容が変数inputに格納されます。

null許容型と警告の扱い

最新のC# (C# 8.0以降) では、参照型のnull許容機能が導入されており、Console.ReadLine()の戻り値はstring? (nullになる可能性がある文字列) として定義されています。

これは、標準入力がリダイレクトされた場合や、入力ストリームが終了した際にnullが返される可能性があるためです。

警告を避けるためには、以下のようにnullチェックを行うか、空文字への変換を行うのが一般的です。

C#
// nullの場合は空文字を代入する例
string input = Console.ReadLine() ?? "";

数値変換の基本:ParseとTryParse

前述の通り、Console.ReadLineで取得したデータは文字列です。

計算やロジックで数値として扱いたい場合は、文字列を数値型に変換する「パース (Parse)」処理が必要になります。

C#にはいくつかの変換方法がありますが、状況に応じて使い分けることが重要です。

int.Parseによる変換

最も直感的な方法は、各数値型に用意されているParseメソッドを使用することです。

C#
using System;

class Program
{
    static void Main()
    {
        Console.Write("年齢を入力してください: ");
        string? input = Console.ReadLine();

        // 文字列を整数に変換
        int age = int.Parse(input ?? "0");

        Console.WriteLine("来年は " + (age + 1) + " 歳ですね。");
    }
}

実行結果の例

年齢を入力してください: 25
来年は 26 歳ですね。

ただし、int.Parseには大きな注意点があります。

もしユーザーが「あいうえお」のような数値以外の文字列を入力した場合、プログラムはSystem.FormatExceptionという例外を発生させて強制終了してしまいます。

安全な変換を行うint.TryParse

実務的なアプリケーションでは、ユーザーが常に正しい入力をするとは限りません。

予期せぬ入力でプログラムが止まらないようにするためには、TryParseメソッドの使用が推奨されます。

TryParseは、変換に成功したかどうかをbool値で返し、変換後の値はout引数を通じて受け取ります。

C#
using System;

class Program
{
    static void Main()
    {
        Console.Write("数値を入力してください: ");
        string? input = Console.ReadLine();

        // 変換に挑戦
        if (int.TryParse(input, out int result))
        {
            // 成功した場合
            Console.WriteLine("変換成功: " + result);
        }
        else
        {
            // 失敗した場合
            Console.WriteLine("エラー: 有効な数値を入力してください。");
        }
    }
}

この方法であれば、数値以外のデータが入力されてもelseブロックが実行されるだけで、アプリがクラッシュすることはありません

ユーザーフレンドリーな入力を実装する上で必須のテクニックです。

複数の入力を一度に取得する方法

競技プログラミングやデータのバッチ処理などでは、「1 2 3」のように1行の中にスペース区切りで複数の値が入力される形式を扱うことがあります。

この場合、1行をまとめて取得した後に分割処理を行います。

String.Splitメソッドの活用

string.Splitメソッドを使うと、特定の文字 (スペースなど) で文字列を分割し、配列として取得できます。

C#
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        Console.WriteLine("3つの数値をスペース区切りで入力してください (例: 10 20 30):");
        string? input = Console.ReadLine();

        if (input != null)
        {
            // スペースで分割して配列にする
            string[] items = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            // 各要素を数値に変換して合計を計算 (LINQを使用)
            int sum = items.Select(int.Parse).Sum();

            Console.WriteLine("合計値: " + sum);
        }
    }
}
実行結果
3つの数値をスペース区切りで入力してください (例: 10 20 30):
15 25 35
合計値: 75

StringSplitOptions.RemoveEmptyEntriesを指定することで、スペースが連続して入力された場合でも余計な空要素を作らずに済み、より堅牢なプログラムになります。

多様なデータ型への変換

C#では、整数以外にも浮動小数点数や真偽値、日付など、さまざまなデータ型への変換が可能です。

浮動小数点数 (double, float) への変換

小数点を含む数値を扱う場合は、double.Parsedecimal.Parseを使用します。

C#
Console.Write("身長(m)を入力してください: ");
string? input = Console.ReadLine();

if (double.TryParse(input, out double height))
{
    Console.WriteLine($"入力された身長は {height}m です。");
}

Convertクラスの利用

Parseメソッドの代わりにSystem.Convertクラスを使用することもできます。

変換後の型Convertクラスのメソッド
intConvert.ToInt32(input)
longConvert.ToInt64(input)
doubleConvert.ToDouble(input)
boolConvert.ToBoolean(input)
DateTimeConvert.ToDateTime(input)

Convert.ToInt32などは、内部的にはint.Parseを呼び出していますが、引数がnullの場合にエラーにならず0を返すという特性があります。

状況に応じて使い分けましょう。

1文字ずつの入力とキー情報の取得

ReadLineは行単位でデータを取得しますが、より低レイヤーな制御が必要な場合には、ReadReadKeyが利用されます。

Console.Readメソッド

Console.Readは、入力ストリームから「次の1文字」を読み込みます。

戻り値はint型であり、文字の文字コード (ASCII/Unicode) を返します。

C#
Console.WriteLine("何か入力してください:");
int charCode = Console.Read();
Console.WriteLine($"最初の文字の文字コード: {charCode} (文字: {(char)charCode})");

Console.ReadKeyメソッド

インタラクティブなコンソールアプリ (「続行するには何かキーを押してください…」など) を作成する際に便利なのが、Console.ReadKeyです。

このメソッドは、キーが押された瞬間に反応し、エンターキーを待たずに処理を続行します。

C#
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("終了するには 'Q' キーを押してください。");

        while (true)
        {
            // キー入力を1つ受け取る (引数にtrueを渡すと入力文字を画面に表示しない)
            ConsoleKeyInfo keyInfo = Console.ReadKey(true);

            if (keyInfo.Key == ConsoleKey.Q)
            {
                Console.WriteLine("Qが押されました。終了します。");
                break;
            }
            else
            {
                Console.WriteLine($"押されたキー: {keyInfo.KeyChar}");
            }
        }
    }
}

ConsoleKeyInfoオブジェクトからは、押されたキーの種類 (Keyプロパティ) や、Shift/Ctrl/Altキーが同時に押されていたかなどの詳細情報を取得できます。

実践的な入力バリデーションの実装

ユーザー入力を伴うプログラムにおいて、最も重要なのは「正しい値が入力されるまで再試行させる」仕組みです。

これにはwhileループとTryParseを組み合わせる手法が一般的です。

数値入力の繰り返し処理

以下は、正の整数が入力されるまで何度も入力を促す実用的なコード例です。

C#
using System;

class Program
{
    static void Main()
    {
        int validNumber = ReadIntFromConsole("1から100までの数値を入力してください: ", 1, 100);
        Console.WriteLine($"受理された数値: {validNumber}");
    }

    /// <summary>
    /// コンソールから範囲内の数値を安全に読み取ります
    /// </summary>
    static int ReadIntFromConsole(string message, int min, int max)
    {
        int result;
        while (true)
        {
            Console.Write(message);
            string? input = Console.ReadLine();

            if (int.TryParse(input, out result) && result >= min && result <= max)
            {
                // 条件を満たす場合はループを抜ける
                break;
            }

            Console.WriteLine($"エラー: {min}から{max}の範囲の数値を入力してください。");
        }
        return result;
    }
}

このようなユーティリティメソッドを作成しておくことで、コードの再利用性が高まり、メインロジックがすっきりと整理されます。

大量データの読み込みとパフォーマンス

大規模なテキストファイルをリダイレクトして標準入力として読み込む場合、Console.ReadLineの速度がボトルネックになることがあります。

パフォーマンスが求められる競技プログラミングなどの場面では、より高速な入力手法が検討されます。

StreamReaderの利用

Console.InStreamReaderのように扱うことで、バッファリングを効かせた高速な読み込みが可能になります。

C#
using System;
using System.IO;

class Program
{
    static void Main()
    {
        // 標準入力をStreamReaderとして取得
        using (var reader = new StreamReader(Console.OpenStandardInput()))
        {
            string? line;
            while ((line = reader.ReadLine()) != null)
            {
                // 高速な読み込み処理
            }
        }
    }
}

通常の対話型アプリではConsole.ReadLineで十分ですが、数万行、数百万行のデータを流し込む場合には、このような手法があることも覚えておくと役立ちます。

入力処理におけるよくある落とし穴

C#の入力処理を実装する上で、開発者が陥りやすいミスや注意すべき仕様についてまとめます。

1. 全角数字の扱い

C#のint.Parsedouble.Parseは、標準の設定では全角数字を数値として認識しません

ユーザーが全角で入力する可能性がある場合は、事前に半角に変換するか、適切なエラーメッセージを出す必要があります。

2. ロケール (文化) による小数の違い

double.Parseは実行環境の地域設定 (Culture) に依存します。

例えば、ヨーロッパの多くの国では小数の区切り文字にコンマ,を使用します。

グローバルなアプリケーションを作成する場合は、CultureInfo.InvariantCultureを指定して、常にドット.を小数点として扱うようにするのが安全です。

C#
using System.Globalization;

// 実行環境に関わらずドットを小数点として解釈
double value = double.Parse(input, CultureInfo.InvariantCulture);

3. 空入力の処理

ユーザーが何も入力せずにエンターキーを押した場合、Console.ReadLine"" (空文字列) を返します。

これを数値変換に回すとエラーになるため、string.IsNullOrWhiteSpace等を使って事前にチェックすることが望ましいです。

まとめ

C#での標準入力取得は、Console.ReadLineを基軸として、用途に応じた型変換やバリデーションを組み合わせることで成り立っています。

  • 基本は Console.ReadLine() で文字列を取得する。
  • 数値に変換する際は、例外を避けるために int.TryParse を活用する。
  • 複数の値が1行に入力される場合は Split メソッドで分割する。
  • ユーザー体験を向上させるために、ループ構造を用いた再入力の仕組みを導入する。
  • 特殊な操作 (1文字入力やリアルタイムなキー取得) には ReadKey を使用する。

これらの技術を習得することで、ユーザーと円滑に対話できる堅牢なコマンドラインアプリケーションを構築できるようになります。

プログラムの入り口となる「入力処理」をマスターすることは、高品質なソフトウェア開発への第一歩です。

まずは簡単な電卓プログラムやクイズアプリの作成から、これらのメソッドを実際に試してみてください。