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

(Tcl) what character encoding set should I use?

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

谢谢!

恐怕,目前没有办法仅通过使用 fconfigure -encoding ?something? 来做到这一点:unicode 编码具有相当实际的意义,并且有一个 feature request 来创建明确的支持对于 UTF-16 变体。

你能做些什么?

因为 unicode 在 Tcl 运行 上 Windows 应该 意味着 UTF-16 与本机字节序 1(Wintel 上的小端),如果您的解决方案应该是一个快速而肮脏的解决方案,请尝试使用 -encoding unicode 看看是否有帮助。

如果您的目标是更可靠或面向未来的跨平台解决方案,我会将通道切换到二进制更多,一次读取两个字节的块中的内容,然后使用

binary scan $twoBytes s n

scan the sequence of two bytes in $twoBytes 作为一个 16 位整数到一个名为 "n" 的变量中,后跟类似

set c [format %c $n]

到$n中的produce a unicode character out of the number,赋值给一个变量

这种方式据说需要更多技巧才能正确获得:

  • 您可能会检查从流中获取的第一个字符,看它是否是字节顺序标记,如果是则将其丢弃。
  • 如果您需要以逐行方式处理流,则必须实现一个能够正确处理 CR+LF 序列的小型状态机。
  • 在执行 read $channelId 2 时,为了获取下一个字符,您应该检查它是否不仅返回 0 或 2,还返回 1——以防文件碰巧损坏——并处理这个问题。

UCS-2 编码与 UTF-16 的不同之处在于后者可能包含所谓的代理对,因此它不是固定长度的编码。因此正确处理 UTF-16 流意味着还检测这些代理对。另一方面,我几乎不相信 MSVS 生成的编译日志可能包含它们,所以我只是假设它是用 UCS-2LE 编码的。


1 真实的故事是 Tcl 唯一保证它处理的 textual 字符串(即那些通过操作文本获得的字符串,而不是通过 binary formatencoding convertto 或以二进制模式读取流)是因为它们是 Unicode(或者更确切地说,是它的 "BMP" 部分)。 但从技术上讲,解释器可能会在它默认使用的 UTF-8 编码和 some 固定长度编码之间切换任何字符串的内部表示,这就是该名称所指的 "unicode"。 "problem" 是 Tcl 文档的任何部分都没有指定内部固定长度编码,因为你 需要 显式转换你输出的任何文本或阅读 to/from 一些特定编码——通过配置流或使用 encoding convertfromencoding convertto 或使用 binary formatbinary scan,无论当前使用哪种精确编码,解释器都会做正确的事情用于您的源字符串值——这一切都是透明的。此外,"standard" Tcl 解释器的下一个版本可能会决定完全放弃此内部功能,或者说,使用 32 位或 64 位整数进行内部固定长度编码。 "non-standard" 解释器做什么(如 Jacl 等)也取决于他们。换句话说,此功能是内部的,不是有关口译员行为的书面合同的一部分。顺便说一下,Tcl 字符串 (UTF-8) 的 "standard" 编码也没有指定——这只是一个实现细节。

在 Tcl v8.6.8 中,我可以使用 fconfigure channelId -encoding unicode 解决同样的问题。