bucle while - Java | InputStreamReader(System.in): no lee la última línea

CorePress2024-01-25  12

he estado intentando resolver este problema. En pocas palabras, no lee la última línea de mi entrada.

Lo que quiero que haga... leer el archivo y salir.

Eso es todo. Funciona bien en un archivo (ejemplo: .txt), pero cuando se trata de System.in, ¡el código no funciona! Molesto, cuando debería ser fácil.

¡Aquí tienes el código y las fotos para recrear!

    StringBuilder strBuilder = new StringBuilder();
    String line;

    // for the last line to "end", I have to do \n! ... but how...?

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

    while((line = br.readLine()) != null) {
        System.out.println(line);
        strBuilder.append(line);
    }

    // Does not reach code
    System.out.println(strBuilder.toString());

Sé que readLine() termina en \n o \r... en este caso, la cuarta línea NO tiene un salto de línea después, así que intenté usar !br.isEmpty() o !br.isBlank para 'veo' que no hay más líneas después de la cuarta línea... pero supongo que me falta algo.

(copia y pega esta información en la consola sin un salto de línea después de la cuarta línea)

1 first line
2 second line
3 third line
4 fourth line

Obtendrás esto

SíObtendrás 4 cuartas líneas para imprimir si presionas ENTER en la consola (porque estás ingresando un "\n"), pero eso no es lo que espero.

Actualmente, no finalizará. No leerá la última línea de entrada del usuario. Estará en un bucle.

Por favor ayuda :)

1

Simplemente presione Intro en su archivo después de la última línea y verifique.

-code_mechanic

28 de marzo de 2021 a las 4:08

1

Su código saldrá si introduce CTRL + 'Z` en una nueva línea y presiona Intro.

- el hutt

28 de marzo de 2021 a las 5:56

@code_mechanic, eso funciona, pero el comportamiento que estaba buscando es que no tengo que hacer eso y dejar que termine solo. Puede que la evaluación que hice tenga errores porque solo tomó en cuenta la entrada del usuario sin especificar un carácter de final de línea o una secuencia de escape, por lo que no leyó la última línea.

& ndash; Flexor

28/03/2021 a las 23:32



------------------------------------

readline() leerá la entrada hasta el carácter de nueva línea o hasta el final del archivo (lo que ocurra primero).

Si lo hace correctamente, es decir, canaliza su archivo a la entrada estándar de su programa Java, debería funcionar. Así: cat myfile.txt | java MiClase o java MiClase < miarchivo.txt. También funcionará si usa FileInputStream en lugar de System.in.

El problema sólo surge cuando escribes la entrada desde la consola a mano. En este caso, BufferedReader no tiene forma de saber cuándo finaliza su entrada, por lo que espera hasta un carácter de nueva línea o hasta el final del archivo. En Linux, simplemente puede presionar Ctrl-D parak la consola para cerrar la entrada estándar al programa java.

6

Hola @jurez, gracias por tu respuesta. Actualmente intenté hacer una evaluación recientemente para una empresa en HackerRank... la plataforma solo se ejecuta para casos de prueba y usted, como programador, no puede hacer mucho más que escribir el código. Entonces Ctrl-D o cualquier otra forma están fuera de discusión. ¿Existe alguna solución? Además, a Sí no le fue tan bien en la evaluación debido a este problema.

- Flexor

28 de marzo de 2021 a las 4:16

Así que escribir en un archivo o hacer cualquier cosa con un archivo también está fuera de discusión.

- Flexor

28 de marzo de 2021 a las 4:19

2

La pregunta aquí es ¿cómo sé dónde termina la entrada? Puede intentar simplemente leer toda la entrada carácter por carácter hasta el final del archivo, recopilarlos en una cadena grande y luego dividirla en líneas separadas.

Jurez

28 de marzo de 2021 a las 4:20

Dentro del bucle while, convertí la cadena readLine en un char[] y los imprimí para ver su número EOL, el número 32 aparece para el EOL en cada línea. pero cuando llega a la última línea (4 cuarta línea), no recorre la última línea en absoluto, parece que está pensando que la última línea es nula?... Me estoy quedando sin ideas

- Flexor

28 de marzo de 2021 a las 4:47

3

@Flexer si hackerrank le envía información y luego no envía una línea de fin de flujo, entonces hackerrank tiene errores y debe presentar un informe de error. Sin embargo, lo dudo bastante. El código que pegaste funciona bien en todas las situaciones, excepto en situaciones estúpidas e imposibles, como entradas que no terminan en una nueva línea y no están cerradas, lo que es literalmente indistinguible de un disco lento.

- rzwitserloot

28 de marzo de 2021 a las 5:07



------------------------------------

En eclipse, pega su entrada, luego hace clic en otro panel/ventana, luego hace clic en la consola y presiona CTRL+Z, la toma como línea nula y sale En el símbolo del sistema en Windows, tendrás que presionar la combinación en nueva línea y presionar Enter.

De lo contrario, tendrás que poner una condición como si la línea estuviera en blanco. Tendrás que presionar Intro para pasar una línea en blanco y salir.

StringBuilder strBuilder = new StringBuilder();
        String line;

        // for the last line to "end", I have to do \n! ... but how...?

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

        while((line = br.readLine()) != null && !line.isBlank()) {
            System.out.println(line);
            strBuilder.append(line);
        }

        // Does not reach code
        System.out.println("Printing result:" + strBuilder.toString());

Salida:

1 first line
2 second line
3 third line
4 fourth line1 first line
2 second line
3 third line

4 fourth line

Printing result:1 first line2 second line3 third line4 fourth line

1

Hola @onkar, exploré esta opción al principio, pero no el comportamiento que buscaba.. Lo que quería que sucediera es que el código leyera la cuarta línea hasta 4 y saliera del bucle. Es posible que haya tenido una evaluación con errores porque la entrada que estaban ingresando para los casos de prueba en HackerRank no contenía una secuencia de escape o un código "\n" al final de la última línea para finalizar el código. ¡Imagínate! 🤷🏽‍♂️

- Flexor

28/03/2021 a las 23:35



------------------------------------

Entonces, para dejar esto a un lado, creo que puede haber sido una evaluación con errores. El siguiente código funciona como se esperaba y, como todos ustedes han dicho, el código funciona bien. ¡No es necesario realizar más investigaciones sobre esto!

public static void main(String[] args) throws IOException {

    StringBuilder strBuilder = new StringBuilder();
    BufferedReader readFile;

    try {
          readFile = new BufferedReader(new FileReader("/src/z_hackerRank_problems/z_IOfile.txt"));
          String contentLine;
          while ((contentLine = readFile.readLine()) != null) {
              strBuilder.append(contentLine).append(" ");
          }
    } catch (IOException ioException) {
        ioException.printStackTrace();
    }
    printHistogram(strBuilder.toString());

}
// z_IOfile.txt | notice '4 fourth line', no line breaks, no "\n" but code still iterates through
1 first line
2 second line
3 third line
4 fourth line

Con FileReader,funciona muy bien. Con InputStreamReader(System.in)... ¡no tanto!

TLDR;

Se supone que el código

lee todas las líneas, pero con InputStreamReader(System.in), no reconoce el carácter/secuencia de final de línea si no hay un código "\n" | "\r" | ejecutando un comando que detiene el ciclo.

Como se dijo en este hilo, es posible que la evaluación de HackerRank necesite algunas revisiones, ya que puede tener errores.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare