2009-11-20 53 views
3

下面的Java代码究竟是干什么的预期:添加回车符时,为什么stdout解码失败?

1  String s = "♪♬♪♪♬♪♪♬♪♪♬♪♪♬♪♪♬♪"; 
2  for(int i=0; i < s.length(); i++) 
3  { 
4   System.out.print(s.substring(i,i+1)); 
5   //System.out.print("\r"); 
6   Thread.currentThread().sleep(500); 
7  } 

但是当我尝试在第5行注释添加回车不言而喻印刷S'。 为什么它,我将如何解决它?

(我也试图与 “\ u240d” 为回车 - 同样的事情)。

编辑:输出进入Mac OS X上一个bash

+0

你想,这些音符输出相互下方或在一行的开头就地覆盖吗? – 2009-11-20 07:20:37

+0

会System.out.println不起作用? – 2009-11-20 07:22:40

+0

仅当他想打印*下*。 – 2009-11-20 07:23:21

回答

1

Java不知道你的源文件是UTF-8。

如果编译

javac -encoding utf8 MyClass.java 

java -Dfile.encoding=utf8 MyClass 

它会工作运行。

(有谁知道为什么UTF-8是不是默认?)

+0

也感谢dtsazza和sascha的其他答案。即使他们(大部分)是正确的,并且可以编写一个解决方法,Jason也可以在没有代码更改的情况下获得简单的解决方案。 – 2009-11-20 11:30:01

4

请同时打印s.length()中,i打赌它超过18 java的字符串表示为UTF-16,字符串。子串只是提取char值。 音符开始在0x1d000 - 他们在一个单一的字符鸵鸟政策契合。 来提取字符串使用完整的财产以后码点/浮雕像 icu project - UCharacterIterator

PS:我不知道,如果你的终端会话可以在任何

+0

假设粘贴到Firefox中的字符在应用程序中是相同的,它们都是基本多语言平面中的U + 266A和U + 266C。 – McDowell 2009-11-20 10:20:19

3

显示这些字符我希望它是由于你的终端是怎么解释输出。

如上面已经指出的那样,所有的音符字形的是多字节字符。除此之外,Java char s为只有16位宽,因此单个char不能可靠地表示在自己的一个Unicode字符 - 以及随后的String.substring方法并不完全多字节友好。

因此,可能发生的情况是,在循环的每次迭代中,Java都会打印出半角。当一对打印机的第一个字节被打印出来时,终端认识到它是多字节字符的前半部分,并且不显示它。当打印下一个字节时,终端将看到与该笔记相对应的完整字符并显示它。

当您取消注释println("\r")时会发生什么情况,是您在每个角色的两半中插入一个换行的中间位置。因此终端永远不会获得字节序列,例如0×26,0x6C代表the note而是得到值为0x26,0x10的,0x6C,0X10所以音符不会被渲染。

+0

这是错误的。 Java字符是16位值。 – 2009-11-20 10:28:35

+0

就这样。我想我只记得它比'int'窄,会保存一个ASCII字符,但不是很多奇特的Unicode字符,然后就是没有考虑/检查。感谢有些尴尬的更正! – 2009-11-20 10:51:45

相关问题