有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java使用扫描仪以UTF8格式输入字符,无法打印文本

我可以将字符串转换为UTF-8格式的数组,但不能像第一个字符串那样将其转换回字符串

public static void main(String[] args) {

    Scanner h = new Scanner(System.in);
    System.out.println("INPUT : ");
    String stringToConvert = h.nextLine();
    byte[] theByteArray = stringToConvert.getBytes();

    System.out.println(theByteArray);
    theByteArray.toString();
    String s = new String(theByteArray);

    System.out.println(""+s);
}

如何将theByteArray打印为字符串


共 (2) 个答案

  1. # 1 楼答案

    提供的代码存在几个问题:

    1. 您无法确保从该字符串获取UTF-8字节数组

      byte[] theByteArray = stringToConvert.getBytes();
      

      返回给定平台上具有默认编码的字节数组,如JavaDoc所述。您实际想要做的是:

      byte[] theByteArray = stringToConvert.getBytes("UTF-8");
      
    2. 您应该检查documentation中的System.out.println()

      System.out.println(theByteArray);
      

      正在调用System.out.println(Object x),它将打印x.toString()的结果。默认情况下,toString()返回给定对象的内存地址

      因此,当您看到表单的输出时:

      INPUT :

      [B@5f1121f6

      inputText

      您看到的是ByteArray的内存位置,然后是给定的文本输入行

    3. 您似乎不理解“x.toString()”方法。记住,Java中的字符串是immutable;String的任何方法都不会更改字符串theByteArray.toString();返回theByteArray;的字符串表示形式。除非将返回的值赋给另一个字符串,否则将抛出该值

      String arrayAsString = theByteArray.toString();
      

      但是,如前所述,返回的字符串将是theByteArray的内存位置。为了打印出theByteArray的内容,需要将其转换为字符串

      String convertedString = new String(theByteArray, Charset.forName("UTF-8"));
      

    假设您的要求是打印转换后的字符串,然后打印原始字符串,那么您的代码应该如下所示:

    public static void main(String[] args) {
    
        Scanner h = new Scanner(System.in);
        System.out.println("INPUT : ");
        String stringToConvert = h.nextLine();
    
        try {
            // Array of the UTF-8 representation of the given String
            byte[] theByteArray;
            theByteArray = stringToConvert.getBytes("UTF-8");
    
            // The converted String
            System.out.println(new String(theByteArray, Charset.forName("UTF-8")));
        } catch (UnsupportedEncodingException e) {
            // We may provide an invalid character set
            e.printStackTrace();
        }
    
        // The original String
        System.out.println(stringToConvert);
    }
    
  2. # 2 楼答案

    String s = new String(theByteArray);
    

    应该是

    String s = new String(theByteArray, Charset.forName("UTF-8"));
    

    这里的根本问题是字符串构造函数不聪明。字符串构造函数无法区分正在使用的字符集,将尝试使用系统标准(通常类似于ASCII或ISO-8859-1)对其进行转换。这就是为什么正常的A-Za-z看起来很合适,但其他一切都开始失败的原因

    byte是一种从-127到127的类型,因此对于UTF-8转换,需要连接连续的字节。字符串构造函数不可能将其与字节数组区分开来,因此默认情况下它将单独处理每个字节(因此,当基本字母数字落入此范围时,它们将始终工作)

    例如:

    String text = "こんにちは";
    byte[] array = text.getBytes("UTF-8");
    String s = new String(array, Charset.forName("UTF-8"));
    System.out.println(s); // Prints as expected
    String sISO = new String(array, Charset.forName("ISO-8859-1")); // Prints 'ããã«ã¡ã¯'
    System.out.println(sISO);