56

我习惯了 c-style getchar(),但似乎 java 没有可比性。我正在构建一个词法分析器,我需要逐个字符地读取输入。

我知道我可以使用扫描仪扫描令牌或行并逐个字符地解析令牌,但这对于跨越多行的字符串来说似乎很笨拙。有没有办法从 Java 的输入缓冲区中获取下一个字符,或者我应该直接使用 Scanner 类?

输入是文件,而不是键盘。

4

9 回答 9

64

使用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类。(如果你觉得受虐,你可以阅读这个字符编码指南。)

(您可能需要注意的一件事是补充 Unicode 字符 - 那些需要存储两个 char 值的字符。有关更多详细信息,请参阅Character类;这是一个可能不适用于家庭作业的边缘情况。)

于 2009-05-01T15:25:10.387 回答
20

结合其他人关于指定字符编码和缓冲输入的建议,我认为这是一个非常完整的答案。

假设您有一个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
}
于 2009-05-01T16:32:27.573 回答
8

另一种选择是不逐个字符地读取内容——将整个文件读入内存。如果您需要多次查看字符,这很有用。一种简单的方法是:

  /** 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();
      }
    }
}
于 2009-05-01T18:32:35.257 回答
7

将输入流包装在缓冲读取器中,然后使用 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);          
        }       
    }   
}
于 2009-05-01T16:00:53.547 回答
1

如果您使用BufferedReader. 这个缓冲的阅读器比阅读器快,所以你可以包装它。

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

这将 line 读入 char 数组。你有类似的选择。看文档。

于 2009-05-01T15:30:08.457 回答
1

将您的阅读器包装在BufferedReader中,该缓冲区维护一个缓冲区,从而可以更快地进行整体读取。然后,您可以使用 read() 读取单个字符(您需要转换)。您还可以使用 readLine() 获取整行,然后将其分成单个字符。BufferedReader 还支持标记和返回,所以如果需要,可以多次读取一行。

一般来说,您希望在实际使用的任何流之上使用 BufferedReader 或 BufferedInputStream,因为它们维护的缓冲区将使多次读取更快。

于 2009-05-01T15:38:55.627 回答
1

如果我是你,我只会使用扫描仪并使用“.nextByte()”。你可以把它转换成一个字符,你很好。

于 2012-08-13T00:42:42.140 回答
0

在 java 5 中添加了新功能,即 Scanner 方法,它可以在 java 中逐个字符地读取输入。

例如; 使用 Scanner 方法 import java.util.Scanner; 在主要方法之后:定义

扫描仪 myScanner = new Scanner(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();

   }
  }
于 2012-01-21T11:05:03.910 回答
-1

这将从文件中每行打印 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());
    }
于 2018-03-03T02:54:35.170 回答