2009-05-01 36 views
37

Estoy acostumbrado al estilo c getchar(), pero parece que no hay nada comparable para java. Estoy construyendo un analizador léxico, y necesito leer el carácter de entrada por carácter.¿Cómo leo la entrada carácter por carácter en Java?

Sé que puedo usar el escáner para escanear un token o línea y analizar el token char-by-char, pero parece difícil de manejar para cadenas que abarcan varias líneas. ¿Hay alguna manera de obtener el siguiente carácter del búfer de entrada en Java, o debería simplemente desconectarme con la clase de escáner?

La entrada es un archivo, no el teclado.

Respuesta

52

Use Reader.read(). Un valor de retorno de -1 significa el fin del flujo; else, envía a char.

Este código lee los datos de caracteres de una lista de argumentos de archivo:

public class CharacterHandler { 
    //Java 7 source level 
    public static void main(String[] args) throws IOException { 
     // replace this with a known encoding if possible 
     Charset encoding = Charset.defaultCharset(); 
     for (String filename : args) { 
      File file = new File(filename); 
      handleFile(file, encoding); 
     } 
    } 

    private static void handleFile(File file, Charset encoding) 
      throws IOException { 
     try (InputStream in = new FileInputStream(file); 
      Reader reader = new InputStreamReader(in, encoding); 
      // buffer for efficiency 
      Reader buffer = new BufferedReader(reader)) { 
      handleCharacters(buffer); 
     } 
    } 

    private static void handleCharacters(Reader reader) 
      throws IOException { 
     int r; 
     while ((r = reader.read()) != -1) { 
      char ch = (char) r; 
      System.out.println("Do something with " + ch); 
     } 
    } 
} 

Lo malo de que el código anterior es que utiliza el conjunto de caracteres por defecto del sistema. Siempre que sea posible, prefiera una codificación conocida (idealmente, una codificación Unicode si puede elegir). Consulte la clase Charset para obtener más información. (Si se siente masoquista, se puede leer this guide to character encoding.)

(Una cosa que usted puede ser que desee tener en cuenta son los caracteres Unicode suplementarios -. Aquellos que requieren dos valores char a tienda Mira la clase Character para más detalles ; este es un caso marginal que probablemente no se aplicará a la tarea.)

+0

¿Puedo utilizar el lector con un archivo, o solo el teclado? – jergason

+3

Normalmente abre un FileInputStream y lo ajusta en un InputStreamReader, especificando la codificación de caracteres. (FileReader desafortunadamente no te permite especificar la codificación.) –

+0

¡Tengo una pregunta sobre esto por favor! Si estoy leyendo un personaje a la vez, ¿por qué necesito un BufferedReader? – Kareem

1

Tiene varias opciones si usa BufferedReader. Este lector de memoria intermedia es más rápido que Reader para que pueda envolverlo.

BufferedReader reader = new BufferedReader(new FileReader(path)); 
reader.read(char[] buffer); 

esto lee la línea en la matriz de caracteres. Tienes opciones similares. Mira la documentación.

1

Envuelva su lector en un BufferedReader, que mantiene un búfer que permite lecturas mucho más rápidas en general. A continuación, puede usar read() para leer un solo carácter (que deberá lanzar). También puede usar readLine() para buscar una línea completa y luego dividirla en caracteres individuales. El BufferedReader también admite marcar y regresar, por lo que si lo necesita, puede leer una línea varias veces.

En general, desea utilizar un BufferedReader o BufferedInputStream en la parte superior de la secuencia que esté utilizando, ya que el búfer que mantienen hará que las lecturas sean mucho más rápidas.

6

Envuelva su secuencia de entrada en un lector de memoria intermedia y luego use el método de lectura para leer un byte a la vez hasta el final de la secuencia.

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 

public class Reader { 

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

     BufferedReader buffer = new BufferedReader(
       new InputStreamReader(System.in)); 
     int c = 0; 
     while((c = buffer.read()) != -1) { 
      char character = (char) c;   
      System.out.println(character);   
     }  
    } 
} 
13

La combinación de las recomendaciones de otros para especificar una codificación de caracteres y amortiguar la entrada, esto es lo que creo que es una respuesta bastante completa.

Asumiendo que tienen un objeto File que representa el archivo que desea leer:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
     new FileInputStream(file), 
     Charset.forName("UTF-8"))); 
int c; 
while((c = reader.read()) != -1) { 
    char character = (char) c; 
    // Do something with your character 
} 
5

Otra opción es la de no leer las cosas en carácter por carácter - leer el archivo en la memoria. Esto es útil si necesita ver los personajes más de una vez.Una forma trivial para hacerlo es:

/** Read the contents of a file into a string buffer  */ 
    public static void readFile(File file, StringBuffer buf) 
     throws IOException 
    { 
    FileReader fr = null; 
    try { 
     fr = new FileReader(file); 
     BufferedReader br = new BufferedReader(fr); 
     char[] cbuf = new char[(int) file.length()]; 
     br.read(cbuf); 
     buf.append(cbuf); 
     br.close(); 
    } 
    finally { 
     if (fr != null) { 
     fr.close(); 
     } 
    } 
} 
+0

El char [] podría usarse también para buscar en el archivo más adelante. StringBuffer solo se utiliza para agregar la matriz de caracteres a StringBuffer y devolverla al punto de ejecución de la llamada. Me imagino que el StringBuffer buf está vacío cuando se trata del método. –

+0

Este es un método de ejemplo para demostrar el concepto. Para utilizar realmente la técnica, sugeriría una biblioteca como Guava – David

+0

Dado que ya está usando un BufferedReader, esto podría ser más lento que establecer una marca y restablecer el buffer del lector. Valdría la pena obtener métricas de rendimiento antes de usar esto. – Txangel

0

en Java 5 nueva característica añadida de que es el método de escáner que da la oportunidad de leer caracteres de entrada de caracteres en Java.

por ejemplo; para su uso Método de escáner import java.util.Scanner; después en el método principal: define

Escáner myScanner = new Scanner (System.in); // para leer el carácter

char anything = myScanner.findInLine ("."). CharAt (0);

que guarde nada solo carácter, si quieres más leer más carácter declarar más objeto como anything1, anything2 ... ejemplo más para su respuesta por favor compruebe en la mano (copiar/pegar)

 import java.util.Scanner; 
    class ReverseWord { 

    public static void main(String args[]){ 
    Scanner myScanner=new Scanner(System.in); 
    char c1,c2,c3,c4; 

    c1 = myScanner.findInLine(".").charAt(0); 
     c2 = myScanner.findInLine(".").charAt(0); 
    c3 = myScanner.findInLine(".").charAt(0); 
    c4 = myScanner.findInLine(".").charAt(0); 

    System.out.print(c4); 
    System.out.print(c3); 
    System.out.print(c2); 
    System.out.print(c1); 
    System.out.println(); 

    } 
    } 
2

Si yo fuera tú, solo usaría un escáner y usaría ".nextByte()". Puedes lanzar eso a un char y estás bien.

0

Esto imprimirá 1 carácter por línea desde el archivo.

try { 

     FileInputStream inputStream = new FileInputStream(theFile); 
     while (inputStream.available() > 0) { 
      inputData = inputStream.read(); 
      System.out.println((char) inputData); 

     } 
     inputStream.close(); 
    } catch (IOException ioe) { 
     System.out.println("Trouble reading from the file: " + ioe.getMessage()); 
    } 
Cuestiones relacionadas