MATLAB:如何显示从文件中读取的UTF-8编码文本?

kjo*_*kjo 25 unicode macos matlab user-interface utf-8

我的问题的主旨是这样的:

如何在Matlab的GUI(OS X)中显示Unicode字符,以便正确呈现它们?

细节:

我有一个存储在文件中的字符串表,其中一些字符串包含UTF-8编码的Unicode字符.我已尝试了许多不同的方法(这里列出太多)以在MATLAB GUI中显示该文件的内容,但没有成功.例如:

>> fid = fopen('/Users/kj/mytable.txt', 'r', 'n', 'UTF-8');
>> [x, x, x, enc] = fopen(fid); enc

enc =

UTF-8

>> tbl = textscan(fid, '%s', 35, 'delimiter', ',');
>> tbl{1}{1}

ans =

ÎÎÎÎÎΠΣΦΩαβγδεζηθικλμνξÏÏÏÏÏÏÏÏÏÏ
>> 
Run Code Online (Sandbox Code Playgroud)

碰巧的是,如果我将字符串直接粘贴到MATLAB GUI中,粘贴的字符串会正确显示,这表明GUI基本上不能显示这些字符,但是一旦MATLAB读入它,它就会更长时间地显示它.例如:

>> pasted = '?????????????????????????????????'

pasted =


>> 
Run Code Online (Sandbox Code Playgroud)

谢谢!

Amr*_*mro 34

在做了一些挖掘后,我在下面的研究结果中提出...考虑这些测试文件:

A.TXT

?????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

b.txt

?????
Run Code Online (Sandbox Code Playgroud)

首先,我们读取文件:

%# open file in binary mode, and read a list of bytes
fid = fopen('a.txt', 'rb');
b = fread(fid, '*uint8')';             %'# read bytes
fclose(fid);

%# decode as unicode string
str = native2unicode(b,'UTF-8');
Run Code Online (Sandbox Code Playgroud)

如果你试图打印字符串,你会得到一堆废话:

>> str
str =
Run Code Online (Sandbox Code Playgroud)

尽管如此,str确实持有正确的字符串.我们可以检查每个字符的Unicode代码,您可以在ASCII范围之外看到(最后两个是不可打印的CR-LF行结尾):

>> double(str)
ans =
  Columns 1 through 13
   915   916   920   923   926   928   931   934   937   945   946   947   948
  Columns 14 through 26
   949   950   951   952   953   954   955   956   957   958   960   961   962
  Columns 27 through 35
   963   964   965   966   967   968   969    13    10
Run Code Online (Sandbox Code Playgroud)

不幸的是,MATLAB似乎无法在GUI中单独显示此Unicode字符串.例如,所有这些都失败了:

figure
text(0.1, 0.5, str, 'FontName','Arial Unicode MS')
title(str)
xlabel(str)
Run Code Online (Sandbox Code Playgroud)

我发现的一个技巧是使用嵌入式Java功能:

%# Java Swing
label = javax.swing.JLabel();
label.setFont( java.awt.Font('Arial Unicode MS',java.awt.Font.PLAIN, 30) );
label.setText(str);
f = javax.swing.JFrame('frame');
f.getContentPane().add(label);
f.pack();
f.setVisible(true);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


在我准备写上述内容时,我找到了另一种解决方案.我们可以使用DefaultCharacterSet未记录的功能并将charset设置为UTF-8(在我的机器上,ISO-8859-1默认情况下):

feature('DefaultCharacterSet','UTF-8');
Run Code Online (Sandbox Code Playgroud)

现在使用正确的字体(您可以更改命令窗口中使用的字体Preferences > Font),我们可以在提示符中打印字符串(请注意,DISP仍然无法打印Unicode):

>> str
str =
?????????????????????????????????

>> disp(str)
ΓΔΘΛΞΠΣΦΩαβγδεζηθικλμνξπÏςστυφχψω
Run Code Online (Sandbox Code Playgroud)

要在GUI中显示它,UICONTROL应该工作(在引擎盖下,我认为它实际上是一个Java Swing组件):

uicontrol('Style','text', 'String',str, ...
    'Units','normalized', 'Position',[0 0 1 1], ...
    'FontName','Arial Unicode MS', 'FontSize',30)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

不幸的是,TEXT,TITLE,XLABEL等仍然显示垃圾:

在此输入图像描述


作为旁注:在MATLAB编辑器中使用包含Unicode字符的m文件源很困难.我使用的是Notepad ++,文件编码为UTF-8而没有BOM.

  • ++谢谢!(MATLAB真的令人失望......) (10认同)
  • 更新:我很高兴地报告MATLAB R2014b(预发布到目前为止)似乎解决了上述大部分问题.命令提示符,Handle图形(新的HG2),uicontrols和直接Java Swing组件都正确呈现Unicode文本,而不必更改`DefaultCharacterSet`(我在配置了默认en-US语言环境的Windows机器上测试它).遗憾的是,编辑器/ IDE仍然会阻塞非ASCII编码的源文件(BOM标记之类的东西无法正确识别) (3认同)