【发布时间】:2012-02-23 12:28:36
【问题描述】:
我是 Java 新手,如果我说了什么愚蠢的话,请耐心等待!我遇到了一些问题,我认为这些问题与 Unicode 相关。
我正在使用Scanner 从文本文件中读取标记化的命令,并以 UTF-8 编码保存。基本上我想首先检查命令是否不等于“command1”或“command2”(在这些情况下我会做其他事情),然后读入一个字符。如果令牌不是单个字符,我将输出错误。
这是我的代码:
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File(args[0]));
while (scanner.hasNext()) {
String command = scanner.next();
if (command.equals("command1")) {
System.out.println("command: command1");
// do something
} else if (command.equals("command2")) {
System.out.println("command: command2");
// do something
} else {
if (command.length() == 1) {
char c = command.charAt(0);
System.out.println("character: " + c);
// do something with c
} else {
System.err.println("error (string was " + command
+ " with length " + command.length() + ")");
}
}
}
}
以及我在 args[0] 中传递文件名以进行测试的文本文件的内容:
command1
x
y
command2
z
└
command1
╒
═
预期输出是:
command: command1
character: x
character: y
command: command2
character: z
character: └
command: command1
character: ╒
character: ═
实际输出为:
command: command1
character: x
character: y
command: command2
character: z
error (string was └ with length 3)
command: command1
error (string was ╒ with length 3)
error (string was ═ with length 3)
如您所见,Java 将非标准字符视为 3 个字符的字符串。奇怪的是,如果我将终端输出中的一个字符复制/粘贴到System.out.println("└".length()) 语句中,它会正确打印1。
关于我哪里出错了有什么想法吗?
谢谢
【问题讨论】:
-
"如果令牌不是单个字符,我将输出错误。"请注意,
String上的length()方法返回 UTF-16 代码单元的数量,而不是字符数量。这些通常但并不总是相同。 -
@bames53 感谢您指出这一点。有没有更好的方法来测试字符串是否是单个字符,或者这只是一个需要注意的潜在问题?
-
这取决于您所说的“单个字符”是什么意思。如果您的用例的合理定义是代码点是一个字符,那么您只需要注意代理对。如果您需要一个允许组合字符之类的定义,那么至少您可能需要一个了解所有关于 Unicode 属性和诸如此类的库。 -- 处理 Unicode 文本很复杂。老实说,很多软件都出错了,但仍然有用。因此,您可能想了解一些有关它的知识,但可能会认为不值得努力实施。
标签: java unicode java.util.scanner