Java: citirea liniilor cu BufferedReader și validare
Citește linii complete în Java cu BufferedReader, validează numerele și detectează sfârșitul intrării. Urmărește suma și cazurile de eroare.
În acest material
BufferedReader citește textul pe linii, păstrând o separare clară între citire și interpretare. O linie goală este text existent, cu lungimea zero; sfârșitul fluxului este reprezentat prin null. Diferența contează când formatul promite un număr precis de valori.
Contractul exemplului
Prima linie conține n, între 0 și 1000. Urmează exact n linii, fiecare cu un întreg din domeniul int, eventual înconjurat de spații. Afișăm suma în long sau INVALID dacă lipsește o linie, un număr nu poate fi interpretat ori n este în afara limitelor. Liniile suplimentare nu fac parte din contract.
Exemplu urmărit pas cu pas
Pentru n=3 și liniile 12, −5, 8, suma evoluează 0→12→7→15. Spațiile din jurul unei valori sunt eliminate înainte de conversie. Dacă linia a doua ar fi goală, nu am considera-o zero: rezultatul ar fi INVALID.
Pentru n=3 și liniile 12, −5, 8, suma evoluează 0→12→7→15.Mărește schema ↗
Cum funcționează soluția
Citirea primei linii este verificată înainte de apelul strip. Conversia cu Integer.parseInt poate semnala NumberFormatException, pe care o tratăm la limita operației complete. Pentru fiecare valoare aplicăm aceleași verificări. Acumulatorul este long încă de la început, astfel încât adunarea a până la 1000 de valori int nu depășește capacitatea lui.
Program complet Java 21
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8));
try {
String first = in.readLine();
if (first == null) {
System.out.println("INVALID");
return;
}
int n = Integer.parseInt(first.strip());
if (n < 0 || n > 1000) {
System.out.println("INVALID");
return;
}
long sum = 0;
for (int i = 0; i < n; i++) {
String line = in.readLine();
if (line == null) {
System.out.println("INVALID");
return;
}
sum += Integer.parseInt(line.strip());
}
System.out.println(sum);
} catch (NumberFormatException ex) {
System.out.println("INVALID");
}
}
}
Salvează programul în Main.java și compilează-l cu javac --release 21 Main.java, apoi rulează java Main. Intrarea se citește din fluxul standard. Rezultatele prezentate mai jos nu depind de data calculatorului, de rețea sau de un serviciu extern.
Corectitudine și cost
După i linii valide, suma este exact suma primelor i valori. O linie invalidă oprește calculul înainte de afișarea unui rezultat parțial. Timpul este proporțional cu numărul total de caractere citite. Memoria reține o singură linie și un acumulator, nu toate valorile; pentru linii cu lungime mărginită, spațiul suplimentar este constant.
Capcana importantă
Nu apela strip pe rezultatul readLine fără verificarea lui null. Nu prinde toate excepțiile doar pentru a ascunde orice problemă: aici tratăm explicit formatul numeric, iar erorile de intrare-ieșire rămân vizibile prin throws IOException. O eroare de mediu nu este același lucru cu o valoare introdusă greșit.
Exersează
Pentru n=0, răspunsul este 0. Pentru două valori Integer.MAX_VALUE, suma este 4294967294, demonstrând necesitatea lui long. Pentru n=2 și o singură linie numerică, răspunsul este INVALID. Înlocuiește o valoare cu 12x și explică de ce prefixul numeric nu trebuie acceptat.
Dacă sintaxa îți este nouă, începe cu primul program Java. Pentru structura prelucrării, reia tipurile, buclele și metodele. Pentru semnalarea intrărilor neacceptate, consultă excepțiile și colecțiile generice.
Comportamentul API este verificabil în documentația Java 21. Exemplele și explicațiile de aici folosesc contractul restrâns precizat mai sus.
Întrebări frecvente
Care este diferența dintre o linie goală și EOF?
O linie goală produce un String cu lungimea zero. EOF, adică sfârșitul fluxului, produce null. Niciuna nu reprezintă implicit numărul zero; programul decide explicit cum le tratează.
De ce folosim strip înainte de parseInt?
Contractul permite spații în jurul valorii. strip elimină spațiul alb de la capete, dar nu transformă un text precum 1 2 într-un singur număr. Validarea rămâne strictă pentru conținut.
De ce suma este long dacă valorile sunt int?
Suma mai multor valori valide poate depăși domeniul fiecărei valori individuale. Cu cel mult 1000 de operanzi int, long acoperă sigur acumularea, inclusiv pentru valori negative.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.