Как читать вводимые символы в Java? - PullRequest
44 голосов
/ 01 мая 2009

Я привык к c-стилю getchar(), но, похоже, нет ничего похожего на Java. Я строю лексический анализатор, и мне нужно читать вводимые символы за символом.

Я знаю, что могу использовать сканер, чтобы сканировать токен или строку и анализировать символ за символом, но это кажется громоздким для строк, охватывающих несколько строк. Есть ли способ просто получить следующий символ из входного буфера в Java, или мне просто отключить класс Scanner?

Вводом является файл, а не клавиатура.

Ответы [ 9 ]

56 голосов
/ 01 мая 2009

Использовать Reader.read () . Возвращаемое значение -1 означает конец потока; иначе, приведите к char .

Этот код считывает символьные данные из списка аргументов файла:

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);
        }
    }
}

Плохая вещь в приведенном выше коде заключается в том, что он использует системный набор символов по умолчанию. Везде, где возможно, предпочитайте известную кодировку (в идеале, кодировку Unicode, если у вас есть выбор). См. Charset класс для получения дополнительной информации. (Если вы чувствуете мазохизм, вы можете прочитать это руководство по кодированию символов .)

(Одна вещь, которую вы, возможно, захотите обратить внимание, - это дополнительные символы Юникода - те, для хранения которых требуется два значения символов. Для получения дополнительной информации см. Класс Символ ; это крайний случай, который вероятно, не относится к домашней работе.)

14 голосов
/ 01 мая 2009

Объединяя рекомендации других для определения кодировки символов и буферизации ввода, вот что я думаю, это довольно полный ответ.

Предполагается, что у вас есть File объект, представляющий файл, который вы хотите прочитать:

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
}
6 голосов
/ 01 мая 2009

Другой вариант - не читать символы по буквам - читать весь файл в память. Это полезно, если вам нужно смотреть на персонажей более одного раза. Один из тривиальных способов сделать это:

  /** 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();
      }
    }
}
6 голосов
/ 01 мая 2009

Оберните ваш входной поток в буферизованном считывателе, затем используйте метод read для чтения одного байта за раз до конца потока.

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);          
        }       
    }   
}
2 голосов
/ 13 августа 2012

На вашем месте я бы просто использовал сканер и использовал ".nextByte ()". Вы можете применить это к персонажу, и все хорошо.

1 голос
/ 01 мая 2009

Оберните ваш читатель в BufferedReader , который поддерживает буфер, позволяющий намного быстрее читать в целом Затем вы можете использовать read () для чтения одного символа (который вам нужно будет привести). Вы также можете использовать readLine () для извлечения всей строки, а затем разбить ее на отдельные символы. BufferedReader также поддерживает маркировку и возврат, поэтому при необходимости вы можете прочитать строку несколько раз.

Вообще говоря, вы хотите использовать BufferedReader или BufferedInputStream поверх любого потока, который вы фактически используете, так как поддерживаемый ими буфер сделает многократное чтение намного быстрее.

1 голос
/ 01 мая 2009

У вас есть несколько вариантов, если вы используете BufferedReader. Этот буферизованный ридер работает быстрее, чем ридер, поэтому вы можете его обернуть

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

это читает строку в массив символов. У вас есть похожие варианты. Посмотри документацию.

0 голосов
/ 03 марта 2018

Это будет печатать 1 символ на строку из файла.

    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());
    }
0 голосов
/ 21 января 2012

В java 5 добавлена ​​новая функция, которая представляет собой метод Scanner, который дает возможность читать вводимые символы за символом в java.

например; для использования сканера метод импорта java.util.Scanner; после основного метода: определить

Scanner myScanner = новый сканер (System.in); // для прочитанного символа

char что угодно = myScanner.findInLine ("."). CharAt (0);

вы что-нибудь храните один символ, если вы хотите больше символов больше, объявите больше объектов, как что-нибудь1, что-нибудь2 ... Еще пример для вашего ответа, пожалуйста, проверьте в ваших руках (копировать / вставить)

     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();

   }
  }
...