我已经习惯了c-style getchar()
,但似乎没有什么比得上java了。我正在构建一个词法分析器,我需要逐个读入输入字符。
我知道我可以使用扫描程序扫描令牌或行并通过令牌char-by-char进行解析,但对于跨越多行的字符串来说这似乎很难处理。有没有办法从Java中的输入缓冲区中获取下一个字符,或者我应该只使用Scanner类插入?
输入是文件,而不是键盘。
答案 0 :(得分:56)
使用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课程。 (如果你感到自虐,你可以阅读this guide to character encoding。)
(您可能需要注意的一件事是补充Unicode字符 - 那些需要存储两个char值的字符。有关详细信息,请参阅Character类;这是一个可能赢得的边缘案例不适用于家庭作业。)
答案 1 :(得分:14)
结合其他人的建议来指定字符编码和缓冲输入,我认为这是一个非常完整的答案。
假设您有一个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
}
答案 2 :(得分:6)
将输入流包装在缓冲的阅读器中,然后使用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);
}
}
}
答案 3 :(得分:6)
另一个选择是不按字符读取内容 - 将整个文件读入内存。如果您需要多次查看字符,这非常有用。一个微不足道的方法是:
/** 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();
}
}
}
答案 4 :(得分:2)
如果我是你,我只需使用扫描仪并使用“.nextByte()”。你可以将它转换为char,你就是好的。
答案 5 :(得分:1)
如果您使用BufferedReader
,则有多种选择。这个缓冲的阅读器比Reader快,所以你可以包装它。
BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);
将行读入char数组。你有类似的选择。看看文档。
答案 6 :(得分:1)
将您的阅读器包裹在BufferedReader中,它保留了一个缓冲区,允许更快的读取速度。然后,您可以使用read()读取单个字符(您需要转换)。您还可以使用readLine()来获取整行,然后将其分解为单个字符。 BufferedReader还支持标记和返回,因此如果需要,您可以多次读取一行。
一般来说,您希望使用BufferedReader或BufferedInputStream 在您实际使用的任何流之上,因为它们维护的缓冲区将使读取速度更快。
答案 7 :(得分:0)
在java 5中添加的新功能是Scanner方法,它有机会在java中逐个字符地读取输入。
例如; for use Scanner方法import java.util.Scanner; 在main方法之后:define
扫描仪myScanner =新扫描仪(System.in); //用于读取字符
char anything = myScanner.findInLine(“。”)。charAt(0);
你有什么东西存储单个字符,如果你想要更多阅读更多字符声明更多对象像anything1,anything2 ... 更多回答您的答案,请检查您的手(复制/粘贴)
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();
}
}
答案 8 :(得分:-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());
}