Альтернатива чтению ввода из System.in Java - PullRequest
5 голосов
/ 06 июня 2010

Я работаю над архивом наборов задач UVa Online Judge как для практики Java, так и для практики структур данных и алгоритмов в целом.

Они дают пример входного файла для отправки в онлайн-судью для использования в качестве отправной точки (это решение проблемы 100).

Вход из стандартного потока ввода (java.lang.System.in) требуется как часть любого решения на этом сайте, но я не могу понять реализацию чтения из System.in, которую они дают в своем примере решения. Это правда, что входной файл может состоять из любых вариаций целых чисел, строк и т. Д., Но каждая программа решения требует чтения основных строк ввода текста из System.in, по одной строке за раз. Должен быть лучший (более простой и надежный) метод сбора данных из стандартного потока ввода в Java, чем этот:

public static String readLn(int maxLg) {
    byte lin[] = new byte[maxLg];
    int lg = 0, car = -1;
    String line = “”;
    try {
        while (lg < maxLg) {
            car = System.in.read();
            if ((car < 0) || (car == ‘\n’)) {
                break;
            }
            lin[lg++] += car;
        }
    } catch (java.io.IOException e) {
        return (null);
    }
    if  ((car < 0) && (lg == 0)) {
        return (null); // eof
    }
    return (new String(lin, 0, lg));
}   

Я действительно удивлен этим. Похоже, что-то извлечено непосредственно из «языка программирования C» от ​​K & R (отличная книга), за исключением модификатора уровня доступа, обработки исключений и т. Д. Несмотря на то, что я понимаю реализацию, кажется, что она написана программистом на C обходит большинство объектно-ориентированной природы Java. Разве нет лучшего способа сделать это, используя класс StringTokenizer или, возможно, вместо этого использовать метод split String или пакет java.util.regex?

1 Ответ

9 голосов
/ 06 июня 2010

Вам определенно не нужно читать по одному байту за раз (вы тоже не читаете в C, для этого fgets ). В зависимости от того, что вы делаете, вы можете использовать BufferedReader или Сканер :

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

Scanner sc = new Scanner(System.in);

BufferedReader имеет метод readLine, в то время как Scanner имеет множество полезных методов, включая nextLine, nextInt, nextDouble и т. Д., Которые обрабатывают конверсии для вас. Он также имеет разделитель на основе регулярных выражений для чтения произвольных токенов.

Одна вещь, которую нужно понять о Java, это то, что она имеет очень четкое различие между двоичными данными (потоки) и символьными данными (читатели и записывающие устройства). Существуют декодеры и кодеры по умолчанию (как указано выше), но вы всегда можете выбрать кодировку.

...