Я новичок в C #, но я очень хорошо знаю Java. Возможно, мне не хватает чего-то простого, чего я просто не знаю, потому что я новичок в этом конкретном языке. Я пытаюсь сделать цикл while, который повторяется до тех пор, пока пользователь не выберет Q. Цикл завершается нормально, но код внутри повторяется 3 раза, прежде чем он останавливается, чтобы предложить пользователю выбор. Почему это случилось?

class MainClass
{


    public static void DisplayMenu() {
        Console.WriteLine("What would you like to do?");
        Console.WriteLine("(D)eposit");
        Console.WriteLine("(W)ithdraw");
        Console.WriteLine("(C)alculateInterest");
        Console.WriteLine("(S)howBalance");
        Console.WriteLine("(Q)uit");
        Console.WriteLine("************************************");
        Console.WriteLine("Make choice by entering first letter of choice,");
        Console.WriteLine("then press ENTER key:");
    }
    static void Main(string[] args) {

        Account account = new Account();
        char choice;
        double amount = 0.0;

        Console.WriteLine("************************************");
        Console.WriteLine("Welcome to Bernard's Bodacious Bank!");
        Console.WriteLine("************************************");
        Console.WriteLine("We have opened your account");
        DisplayMenu();
        choice = Char.ToUpper((char)Console.Read());

        while (!choice.Equals('Q')) {

            DisplayMenu();
            choice = Char.ToUpper((char)Console.Read()); 

        }

        account.ShowTransactions();
        Console.ReadKey();
    }
}
0
benjaminhmlucas 20 Окт 2017 в 21:18

3 ответа

Лучший ответ

Причина, скорее всего, в том, что вы используете Console.Read(), который будет обрабатывать следующий символ во входном потоке, который включает в себя символы \n и \r, когда пользователь нажал Enter , Эти символы затем сразу же обрабатываются внутри вашего цикла при вызовах Console.Read().

Если вам нужен только один символ, вы можете вместо этого использовать Console.ReadKey(), который возвращает первый ключ (как тип ConsoleKeyInfo), который вводит пользователь. Затем вы можете сравнить его Key свойство, например:

Console.WriteLine("************************************");
Console.WriteLine("Welcome to Bernard's Bodacious Bank!");
Console.WriteLine("************************************");
Console.WriteLine("We have opened your account");

double amount = 0.0;
ConsoleKeyInfo choice;

do
{
    DisplayMenu();
    choice = Console.ReadKey();
} while (choice.Key != ConsoleKey.Q);

В качестве альтернативы, если вы DO хотите разрешить им нажимать клавишу ввода, вам следует использовать метод Console.ReadLine() и проверить, что это StartsWith:

DisplayMenu();
string choice = Console.ReadLine();

while (!choice.StartsWith("Q", StringComparison.OrdinalIgnoreCase))
{
    DisplayMenu();
    choice = Console.ReadLine();
}

Вот пример того, как вы можете обрабатывать ввод. Предполагается, что у вас есть методы, которые можно вызывать для каждого выбора:

var quit = false;

while(!quit)
{
    DisplayMenu();

    var choice = Console.ReadKey();

    switch (choice.Key)
    {
        case ConsoleKey.D:
            Deposit();
            break;
        case ConsoleKey.W:
            Withdrawl();
            break;
        case ConsoleKey.C:
            CalcInterest();
            break;
        case ConsoleKey.S:
            ShowBalance();
            break;
        case ConsoleKey.Q:
            quit = true;
            break;
        default:
            Console.WriteLine("Invalid entry, try again");
            break;
    }
}
1
Rufus L 20 Окт 2017 в 19:39

Из документации MSDN:

Метод Read блокирует возврат при вводе символов ввода; он заканчивается, когда вы нажимаете клавишу Enter. Нажатие клавиши Enter добавляет зависящую от платформы последовательность завершения строки к вашему вводу (например, Windows добавляет последовательность перевода строки после возврата каретки). Последующие вызовы метода Read возвращают ваш ввод по одному символу за раз. После получения последнего символа Read снова блокирует его возврат, и цикл повторяется.

В Windows «зависимая от платформы последовательность завершения строки» равна \r\n. Поэтому, когда вы набираете A, а затем Enter, вы фактически посылаете 3 нажатия клавиш для обработки вашей программы.

Также из документации MSDN:

Метод ReadLine или свойство KeyAvailable и метод ReadKey предпочтительнее использования метода Read.

1
Icemanind 20 Окт 2017 в 18:34

Это кажется самым простым ответом. Используйте метод read key, затем используйте choice.Key и ConsoleKey.Q. Спасибо за помощь, ребята! Это указало мне в правильном направлении!

Static void Main (string [] args) {

        Account account = new Account();
        double amount = 0.0;
        ConsoleKeyInfo choice;

        Console.WriteLine("************************************");
        Console.WriteLine("Welcome to Bernard's Bodacious Bank!");
        Console.WriteLine("************************************");
        Console.WriteLine("We have opened your account");
        DisplayMenu();
        choice = Console.ReadKey();
        while (choice.Key != ConsoleKey.Q) {
            switch (choice.Key) {
                case ConsoleKey.D:
                    Console.WriteLine("found d!");
                    break;
                default:
                    Console.WriteLine("Input Error!");
                    break;
            }
        }

        account.ShowTransactions();
        Console.ReadKey();
    }
0
benjaminhmlucas 20 Окт 2017 в 19:10