Java, BufferedReader] Разница между Integer.parseInt(br.readline()) и br.read()-‘0’

#java #ascii #bufferedreader

Вопрос:

Я пытаюсь рассчитать a b с помощью BufferedReader . Я попробовал два кода, каждый из которых использует read() и readLine() , но я не могу понять, почему первый код работает, а второй-нет. Есть ли какая-то разница между Integer.parseInt(br.readline()) и br.read()-'0' ? Разве они оба не возвращают примитивный int? Вот первый код. Это прекрасно работает.

 package level3;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.StringTokenizer;

public class ABPlusFast {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;
        int t = Integer.parseInt(br.readLine());
        
        for (int i=0; i<t; i  ) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            bw.write(a b "n");
        }
        bw.flush();
        bw.close();
    }
}

 

Вот второй код, который не работает. Если я введу число в качестве входных данных, оно вернет NoSuchElementException() вход StringTokenizer.class .

 package level3;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.StringTokenizer;

public class ABPlusFast {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;
        int t = br.read();
        
        for (int i=0; i<(t-'0'); i  ) {
            st = new StringTokenizer(br.readLine());
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());
            bw.write(a b "n");
        }
        bw.flush();
        bw.close();
    }
}

 

Комментарии:

1. Можете ли вы описать, как второй код не работает?

2. И на каком входе вы используете каждый из них?

3. @Sweeper @tgdavies Если я, например, введу номер в консоли 5 , что означает, что я хочу пять раз использовать этот калькулятор плюс, то я получу NoSuchElementException() вход StringTokenizer.class .

Ответ №1:

Невозможно сказать вам, почему одна версия «работает», а другая «не работает» … если вам не ясно, о:

  1. что вы подразумеваете под «работает» и «не работает» в этом контексте, и
  2. именно то, что вы предоставляете.

Однако существуют явные различия между тем, что делают эти две версии.

Первая версия считывает всю первую строку стандартного ввода и пытается проанализировать ее как целое число.

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

  • Если в номере в первой строке две или более цифр, он будет игнорировать все, кроме первой.
  • Если первый символ не является цифрой, плохие вещи произойдут 1.
  • Если стандартный входной поток пуст, read() он вернется -1 , и произойдут плохие вещи 1.
  • Это не занимает остальную часть первой строки. Поэтому, когда вы затем вызовете nextLine() первую итерацию цикла, она вернет остальную часть первой строки. Когда вы затем попытаетесь обозначить и проанализировать это, вероятно, произойдут плохие вещи 1.

Я бы рискнул сказать, что вторая версия неверна.


1. Я не собираюсь вдаваться в подробности … потому что «плохие вещи» будут зависеть от фактического ввода.

Комментарии:

1. Основываясь на ваших комментариях выше, это 4-й пункт, который вызывает исключения.