(Tcl)我应该使用什么字符编码集?

时间:2015-01-14 16:43:08

标签: encoding tcl

所以我试图用Tcl打开并解析一些旧的Visual Studio编译日志文件;我唯一的问题是文件是一个奇怪的编码。在使用Notepad ++检查它们时,它们似乎是在UCS-2 Little Endian'编码。两个问题:

  • Tcl中是否有任何命令允许我查看文件的字符编码?我知道有encoding system告诉我系统编码。
  • 使用encoding names Tcl告诉我可用的编码名称如下:

    cp860 cp861 cp862 cp863 tis-620 cp864 cp865 cp866 gb12345 gb2312-raw cp949 cp950 cp869 dingbats ksc5601 macCentEuro cp874 macukraine jis0201 gb2312 euc-cn euc-jp macThai iso8859-10 jis0208 iso2022-jp macIceland iso2022 iso8859-13 jis0212 iso8859-14 iso8859-15 cp737 iso8859-16 big5 euc-kr macRomania macTurkish gb1988 iso2022-kr macGreek ascii cp437 macRoman iso8859-1 iso8859-2 iso8859-3 macCroatian koi8-r iso8859-4 ebcdic iso8859-5 cp1250 maccyrillic iso8859-6 cp1251 macDingbats koi8- u iso8859-7 cp1252 iso8859-8 cp1253 iso8859-9 cp1254 cp1255 cp850 cp1256 cp932 identity cp1257 cp852 macJapan cp1258 shiftjis utf-8 cp855 cp936 symbol cp775 unicode cp857

    鉴于此,在fconfigure -encoding命令中使用哪个适当的名称来读取这些UCS-2 Little Endian编码文件并将其转换为UTF-8以供使用?如果我正确理解fconfigure命令,我需要指定源文件的编码类型而不是我想要的编码类型;我只是不知道上面列表中的哪个选项与UCS-2 Little Endian相对应。稍微阅读一下后,我看到UCS-2是UTF-16字符编码的前身,但是这个选项也不在这里。

谢谢!

2 个答案:

答案 0 :(得分:6)

我很害怕,目前只能使用fconfigure -encoding ?something?无法做到这一点:unicode编码具有相当不明智的意义,而且有unicode {-encoding unicode 3}}为UTF-16变体创建显式支持。

你可以做些什么?

由于在Windows 上运行的Tcl中的binary scan $twoBytes s n 表示具有本机字节序 1 (Wintel上的小端)的UTF-16,如果您的解决方案是假设的要快速而肮脏,只需尝试使用$twoBytes,看看是否有帮助。

如果你的目标是更加防弹或面向未来的跨平台解决方案,我会将频道切换为二进制,一次读取两个字节的内容,然后使用

set c [format %c $n]

read $channelId 2中的feature request作为16位整数,变为名为" n"的变量,后跟类似

的变量
binary format
在$ n中

scan the sequence of two bytes,并将其分配给变量。

这种方式可能需要更多的技巧才能正确使用:

  • 您可以检查从流中获取的第一个字符,看它是否为字节顺序标记,如果是,则将其删除。
  • 如果您需要以线方式处理流,则必须实现一个能够正确处理CR + LF序列的小型状态机。
  • 在执行encoding convertto时,为了得到下一个字符,你应该检查它不只返回0或2,还要检查1 - 如果文件碰巧被破坏了, - 并处理它。

UCS-2编码与UTF-16的不同之处在于后者可能包含所谓的代理对,因此它不是固定长度的编码。因此处理UTF-16流恰当地暗示也检测那些代理对。另一方面,我很难相信MSVS生成的编译日志可能包含它们,所以我只是假设它在UCS-2LE中编码。


1 真实的故事是Tcl唯一保证它处理的文本字符串(即通过操纵文本获得的字符串,而不是encoding convertfromencoding convertto或以二进制模式读取流)是他们的Unicode(或者更确切地说," BMP"它的一部分)。 但从技术上讲,解释器可能会在默认情况下使用的UTF-8编码与某些固定长度编码之间切换任何字符串的内部表示形式,这就是该名称所引用的编码" unicode& #34 ;. "问题"是的,Tcl文档的任何部分都没有指定内部固定长度编码,因为您需要显式转换您输出或读取的任何文本到某些特定编码 - 通过配置流或使用binary formatbinary scan或使用Jacl和{{1}},解释器将做正确的事情,无论它目前用于源字符串的精确编码价值 - 它都是透明的。此外,"标准的下一个版本" Tcl解释器可能决定完全删除此内部功能,或者说,使用32位或64位整数进行内部固定长度编码。无论什么"非标准"口译员(如{{1}}等)也取决于他们。换句话说,此功能是内部的,并不是有关解释程序行为的文档合同的一部分。顺便说一下,"标准" Tcl字符串(UTF-8)的编码也没有这样指定 - 它只是一个实现细节。

答案 1 :(得分:0)

在Tcl v8.6.8中,我可以使用fconfigure channelId-编码unicode解决同一问题。