【问题标题】:Java Unicode Problems (I think)Java Unicode 问题(我认为)
【发布时间】: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


【解决方案1】:

当您在 Java 中打开文件时,编码(如果您没有指定)取自 file.encoding 系统属性。这几乎永远不会设置为您想要的东西(如果您像我一样,您总是想要 UTF-8)。

要解决此问题,请在创建 Scanner 时明确指定您的字符集:

Scanner scanner = new Scanner(new File(args[0]), "UTF-8");

【讨论】:

    【解决方案2】:

    我怀疑您的问题确实来自编码不匹配。 您是否尝试过在扫描器的构造函数中传递字符集?

    您的代码在我的系统(Arch Linux 64b,java 6.0.30)上完美运行,默认语言环境为 UTF-8。如果您运行 Windows,您的语言环境可能是 Win-CP1252,扫描仪可以使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 2013-01-27
      • 2016-07-29
      • 2014-10-17
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多