Как читать ввод по-символам в Java?

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

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

Ввод - это файл, а не клавиатура.

Ответ 1

Используйте Reader.read(). Возвращаемое значение -1 означает конец потока; else, отбрасывается на 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. (Если вы чувствуете мазохистство, вы можете прочитать это руководство по кодировке символов.)

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

Ответ 2

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

Предполагая, что у вас есть объект 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
}

Ответ 3

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

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

Ответ 4

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

  /** 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();
      }
    }
}

Ответ 5

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

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

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

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

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

char ничего = myScanner.findInLine( "." ). charAt (0);

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

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

   }
  }