2

ReadLine()に0を入力すると、48になります。

これはバグですか?

class Program
{
    static void Main(string[] args)
    {
        string name;
        int age;

        readPerson(out name, out age);
    }
    static void readPerson(out string name, out int age)
    {
        Console.Write("Enter name: ");
        name = Console.ReadLine();
        Console.Write("Enter age: ");
        age = Console.Read();
        Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString());
    }
}
4

3 に答える 3

10

いいえ、バグではありません。

Console.Read()入力された文字のASCII文字コードを返します。数字0のASCIIコードは48、数字1のASCIIコードは49というように続きます。out48という数字を恣意的に追加したり、パラメーターとは関係がありません。

行を読み取り、それに応じて入力を整数にキャストする必要があります。

Console.Write("Enter age: ");
age = Convert.ToInt32(Console.ReadLine());

Read()何らかの理由で使用する必要がある場合は、コメントで述べたように、結果をにキャストする必要がありますcharint ageまた、変数をからに変更する必要がありますchar age

class Program
{
    static void Main(string[] args)
    {
        string name;
        char age;

        readPerson(out name, out age);
    }
    static void readPerson(out string name, out char age)
    {
        Console.Write("Enter name: ");
        name = Console.ReadLine();
        Console.Write("Enter age: ");
        age = (char) Console.Read();
        Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString());
    }
}

一度に読み取ることRead()ができるのは1文字のみであることに注意してください。したがって、1桁を超える年齢を解析する必要がある場合、これは機能せず、ReadLine()代わりに使用する方がはるかに優れています。

于 2012-02-06T06:31:08.510 に答える
7

MSDNのドキュメントによると、Console.Readメソッドは次を返します。

入力ストリームの次の文字、または現在読み取る文字がない場合は負の文字(-1)。

したがって、実際に表示されているのは、現在ストリーム上にある最初の文字(つまり、最後の2回のEnterプッシュの間に受信した文字)だけです。

ユニットテスト中、値が48シフトしたように見えました。これは、「0」から「9」までの文字のASCII値が、ご想像のとおり、「0」の場合は48、「」の場合は49であるためです。 1'など:

ASCIIテーブル

変換を指定しなかったため、ストリームの内容は「自動的に」char値として読み取られ、呼び出しRead()てASCIIの10進数に相当するものが表示されました。

これは、次の簡単なテストを使用して確認できます。

static void TestRead()
{
    int current = 0;

    Console.Write("Enter 1: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    Console.Write("Enter 22: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);
}

その結果、次のようになります。

出力

Read()ストリームから1文字を取得し、それに相当するASCII10進数を取得するための連続呼び出しに気付くでしょう。また、Windowsがキーのストロークごとにキャリッジリターン(ASCII 13)とラインフィード(ASCII 10)シーケンスを追加する方法にも注意しEnterてください。これは、プログラムが忠実にエコーバックします。

このテストメソッドを少し変更すると、特定の方向性がないという点を理解するのに役立ちます。ランタイムは、入力ストリームの内容を文字として解釈します。

static void TestReadModified()
{
    int current = 0;

    Console.Write("Enter a: ");
    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);

    current = Console.Read();
    Console.WriteLine("Next char: {0}", current);
}

予想どおり、上記のメソッドは文字'a'のASCII値を返します。

手紙の出力

他の人がすでに述べたように、これは簡単に修正できます。値をとして解釈することをランタイムに通知するだけですint。少なくとも、受け取った入力が数値であることを確認することもおそらく良い考えです。

static void readPerson(out string name, out int age)
{
    Console.Write("Enter name: ");
    name = Console.ReadLine();

    Console.Write("Enter age: ");

    // in this case, we could simply use tempAge (defaults to 0)
    // but it's just practice to check TryParse's success flag
    int tempAge;
    var success = Int32.TryParse(Console.ReadLine(), out tempAge);

    age = success ? tempAge : 0;

    Console.WriteLine("Name: {0}; Age: {1}", name, age);
    Console.ReadLine();
}
于 2012-02-06T08:28:46.990 に答える
1

番号のASCIIコードが印刷されています。Console.Read()標準入力から次の文字を読み取り、intを返すことに注意してください。したがって、(整数0ではなく)文字0を入力すると、ASCIIコード48などが返されます。また、このASCIIコードは文字の整数コード(たとえば0)であるため、このコードのintへの変換は冗長です。Console.ReadLine年齢を文字列として読み取り、整数に変換します。これは、int.TryParseなどで実行できます。

于 2012-02-06T06:32:52.193 に答える