2012-05-31 32 views
8

estoy leyendo desde un archivo que dice algo así como en una sola línea:¿Cómo hacer que Scanner lea correctamente los caracteres de escape?

Hello World!\nI've been trying to get this to work for a while now.\nFrustrating.\n 

Y mi escáner lee que desde el archivo y la pone en una cadena:

Scanner input = new Scanner(new File(fileName)); 
String str = input.nextLine(); 
System.out.print(str); 

Ahora, quiere que la salida sea:

Hello World! 
I've been trying to get this work for a while now. 
Frustrating. 

Pero en vez de eso obtengo exactamente lo mismo que la entrada. Es decir, cada \ n está incluido en el resultado y todo está en una línea en lugar de líneas separadas.

Pensé que el escáner podría leer el carácter de escape correctamente, pero en su lugar, es copiarlo en la cadena como si fuera \\ n.

Respuesta

3

Si \n que está escrito es el archivo no se puede utilizar nextLine() porque no hay \n (fin de línea) pero en su lugar hay \\n (dos caracteres).

En lugar de tratar con un delimitador:

Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt")); 
    sc.useDelimiter("\\\\n"); 
    while(sc.hasNext()){ 
     System.out.println(sc.next()); 
    } 

Salida:

Hello World!

He estado tratando de hacer que esto funcione por un tiempo.

Frustrante.

EDIT:

Si desea leer el archivo y reemplazar el \n en el texto con EOL real. Simplemente puede usar:

Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt")); 

//loop over real EOL 
while(sc.hasNextLine()){ 

    //Replace the `\n` in the line with real EOL. 
    System.out.println(sc.nextLine().replace("\\n", System.getProperty("line.separator"))); 
} 
4

No, Scanner no hará eso por usted. Tendrás que hacer la traducción tú mismo.

(Tenga en cuenta que si utiliza algo así como sc.useDelimiter("\\\\n") como otros han sugerido que está rompiendo la funcionalidad del next() método ordinario y se nextLine() puede no funcionar como se espera.)

Aquí hay un bosquejo de cómo iba a resolverlo :

Cambio

Scanner input = new Scanner(new FileReader(fileName)); 

a

Scanner input = new Scanner(new JavaEscapeReader(new FileReader(fileName))); 
          ^^^^^^^^^^^^^^^^^^^^^      ^

donde JavaEscapeReader se extendería FilterReader así:

class JavaEscapeReader extends FilterReader { 

    JavaEscapeReader(Reader in) { 
     super(in); 
    } 

    @Override 
    public int read() throws IOException { 
     int ch = super.read(); 
     switch (ch) { 
     case '\\': 
      switch (super.read()) { 
      case '\\': return '\\'; 
      case 'n': return '\n'; 
      case 't': return '\t'; 
      case 'f': return '\f'; 
      // ... 
      default: 
       throw new IOException("Invalid char sequence."); 
      } 
     default: 
      return ch; 
     } 
    } 

    @Override 
    public int read(char[] cbuf, int off, int len) throws IOException { 
     int i = 0, ch; 
     while (i < len && -1 != (ch = read())) 
      cbuf[i++] = (char) ch; 
     return i == 0 ? -1 : i; 
    } 
} 

Dado un archivo de entrada con el contenido

Line1\nLine2 
Line3\nLine3 

el programa

Scanner sc = new Scanner(new JavaEscapeReader(new FileReader("filename.txt"))); 
while (sc.hasNextLine()) 
    System.out.println(sc.nextLine()); 

impresiones

Line1 
Line2 
Line3 
Line4 

Otra opción es utilizar StringEscapeUtils.unescapeJava y procesar las cadenas de lectura.

2

Puede usar Scanner.useDelimiter para establecer su propio delimitador. En su caso el uso de comillas dobles \\n:

s.useDelimiter("\\\\n"); 

Ejemplo:

Scanner s = new Scanner("Hello World!\\nI've been trying to get this to " + 
         "work for a while now.\\nFrustrating.\\n"); 
s.useDelimiter("\\\\n"); 

System.out.println(s.next()); 
System.out.println(s.next()); 
System.out.println(s.next()); 

Salidas:

Hello World! 
I've been trying to get this to work for a while now. 
Frustrating. 
+0

Digamos que necesito la entrada almacenada en una Cadena para un uso fácil en el futuro. ¿Hay alguna forma de que pueda almacenar correctamente los caracteres de escape simplemente yendo directamente a System.out? – sangh

+1

@ user1427895 Ver mi edición. –

+0

@ alain.janinm ¡Maravilloso! Eso parece haberlo hecho. ¡Gracias! – sangh

Cuestiones relacionadas