无法在Windows控制台中正确打印非英文字符,如ë

时间:2017-10-31 19:04:51

标签: java unicode

出于某种奇怪的原因,我似乎无法在Java中打印ë。

> --------------------------------------------------------------------------- ValueError                                Traceback (most recent call
> last) ~\Anaconda3\lib\site-packages\IPython\core\formatters.py in
> __call__(self, obj)
>     691                 type_pprinters=self.type_printers,
>     692                 deferred_pprinters=self.deferred_printers)
> --> 693             printer.pretty(obj)
>     694             printer.flush()
>     695             return stream.getvalue()
> 
> ~\Anaconda3\lib\site-packages\IPython\lib\pretty.py in pretty(self,
> obj)
>     363                 if cls in self.type_pprinters:
>     364                     # printer registered in self.type_pprinters
> --> 365                     return self.type_pprinters[cls](obj, self, cycle)
>     366                 else:
>     367                     # deferred printer
> 
> ~\Anaconda3\lib\site-packages\IPython\lib\pretty.py in inner(obj, p,
> cycle)
>     594         if basetype is not None and typ is not basetype and typ.__repr__ != basetype.__repr__:
>     595             # If the subclass provides its own repr, use it instead.
> --> 596             return p.text(typ.__repr__(obj))
>     597 
>     598         if cycle:
> 
> ~\Anaconda3\lib\site-packages\geojson\base.py in __repr__(self)
>      25 
>      26     def __repr__(self):
> ---> 27         return geojson.dumps(self, sort_keys=True)
>      28 
>      29     __str__ = __repr__
> 
> ~\Anaconda3\lib\site-packages\geojson\codec.py in dumps(obj, cls,
> allow_nan, **kwargs)
>      30 def dumps(obj, cls=GeoJSONEncoder, allow_nan=False, **kwargs):
>      31     return json.dumps(to_mapping(obj),
> ---> 32                       cls=cls, allow_nan=allow_nan, **kwargs)
>      33 
>      34 
> 
> ~\Anaconda3\lib\json\__init__.py in dumps(obj, skipkeys, ensure_ascii,
> check_circular, allow_nan, cls, indent, separators, default,
> sort_keys, **kw)
>     236         check_circular=check_circular, allow_nan=allow_nan, indent=indent,
>     237         separators=separators, default=default, sort_keys=sort_keys,
> --> 238         **kw).encode(obj)
>     239 
>     240 
> 
> ~\Anaconda3\lib\json\encoder.py in encode(self, o)
>     197         # exceptions aren't as detailed.  The list call should be roughly
>     198         # equivalent to the PySequence_Fast that ''.join() would do.
> --> 199         chunks = self.iterencode(o, _one_shot=True)
>     200         if not isinstance(chunks, (list, tuple)):
>     201             chunks = list(chunks)
> 
> ~\Anaconda3\lib\json\encoder.py in iterencode(self, o, _one_shot)
>     255                 self.key_separator, self.item_separator, self.sort_keys,
>     256                 self.skipkeys, _one_shot)
> --> 257         return _iterencode(o, 0)
>     258 
>     259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
> 
> ValueError: Out of range float values are not JSON compliant

它应该打印public class Eindopdracht0002test { public static void main(String[] args) { System.out.println("\u00EB"); } } (dutch为比利时),但它会返回"België"

有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

在UTF-8 ë中写为11000011 10101011(来源:https://unicode-table.com/en/00EB)。
Windows中的控制台使用的代码页是8位字符映射(您可以使用chcp命令检查控制台的代码页)。这意味着当ë作为11000011 10101011位发送到输出流(控制台)时,控制台将其视为两个字符,在850 code page中(根据您的注释)映射到:

  • - 11000011(十进制195)
  • ½ - 10101011(十进制171)

如果您不想使用UTF-8编码,您可以创建单独的Writer并指定不同的编码,这将根据该编码将字符转换为字节。为此,您可以使用

OutputStreamWriter(OutputStream out, String charsetName)

在您的情况下可能看起来像

OutputStreamWriter(System.out, "cp850") osw = OutputStreamWriter(System.out, "cp850");
//  needed encoding ------------^^^^^

因为您希望将具有指定编码的字符发送到标准输出流。

要使用println方法并确保它会自动刷新其数据,您可以将创建的OutputStreamWriter包裹在

PrintWriter(OutputStream out, boolean autoFlush)

喜欢

PrintWriter out = new PrintWriter(osw, true);

您也可以在一行中完成这两件事:

PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out, "cp850"), true);

现在,如果您使用out.println("\u00EB");,则应使用识别ë字符并使用cp850编码来定位其映射(137)并发送正确的字节表示(此处) 10001001)到System.out(控制台)。