Почему строка внутри метода println отображается дважды?

В следующем коде почему строка внутри метода println отображается дважды. Что мне нужно сделать, чтобы показать сообщение один раз за итерацию

package practicejava;

public class Query {

    public static void main(String[] args) throws java.io.IOException {
        System.out.println("Guess a capital letter Character");
        while ((char) System.in.read() != 'S') {
            System.out.println("wrong.guess again to finish the program");
        }

    }
}

4 ответа

Когда пользователь пишет в консоли символы, чтобы подтвердить факт, что его ввод готов для передачи в приложение, он нажимает клавишу ввода. Но консоль не передает только предоставленные символы, она также добавляет к входному потоку (System.in) символ (ы) разделителя строки, зависящий от ОС, после нее. Некоторые ОС используют \r или же \n (это отдельные символы, \x это просто обозначение, чтобы представлять их) другие, как Windows, используют \r\n (два символа) последовательность в качестве разделителя строк.

Теперь эти дополнительные символы также читаются System.in.read() и так как они не равны SSystem.out.println("wrong.guess again to finish the program"); выполняется дополнительное время.

Чтобы избежать таких проблем, вместо работы с необработанными данными через System.in.read() рассмотреть возможность использования классов, призванных сделать нашу жизнь проще, как java.util.Scanner

Scanner sc = new Scanner(System.in);
System.out.println("Guess a capital letter Character");
String response = sc.nextLine();
while(!response.equals("S")){
     System.out.print("incorrect data, please try again: ");
     response = sc.nextLine();
}

Вы могли бы использовать Scanner добиться того же.

Scanner sc = new Scanner(System.in);
System.out.println("Guess a capital letter Character");
while(!sc.nextLine().equals("S")) {
    System.out.println("wrong.guess again to finish the program");
}
sc.close();

Что вы можете сделать, это использовать Scanner чтобы получить ввод пользователя:

package practicejava;

import java.util.Scanner;

public class Query {

    public static void main(String[] args) throws java.io.IOException {
        Scanner s = new Scanner(System.in);
        char c;

        do {
            System.out.println("Guess a capital letter Character");

            c = s.next().charAt(0);

            if (c != 's') {
                System.out.println("Wrong! Guess again to finish the program.");
            }
        } while(c != 's');
    }
}

s.next() получит ввод от пользователя в виде строки и s.next().charAt(0) вернет первый символ в этой строке.

Это потому, что первый символ, который вы прочитали, является буквой, которую вы набрали, а затем есть второй цикл, где символом является возвращаемая строка.

Например, на моем компьютере с Linux, если я ввожу "E" и затем нажимаю ввод, первый цикл обрабатывает символ 69 "E", а затем есть второй цикл для обработки возврата каретки (символ 10).

Другие вопросы по тегам