如何在Tcl中将十六进制字符串转换为Unicode字符字节字符串

时间:2013-12-19 14:19:27

标签: tcl

假设我有一个像905082这样的十六进制字符串。

现在我想将它转换为Tcl中相应的unicode字符。我使用了以下代码:

set charstring ""
  set hexstring 905082
  set len [string length $hexstring]
  for {set i 0} {$i < [expr $len / 2]} {incr i} {
    set j [expr 2 * $i]
    set char [string range $hexstring $j [expr $j + 1]]

    set charstring $charstring[format %c [format %i 0x$char]]
  }
  puts $charstring

但它不起作用......可能它包含这样的十六进制值,表示不可打印的unicode字符。那么我怎么能这样做,以便我可以将十六进制字符串转换为unicode字节串,以便我可以使用SWIG将其传递给C函数?

2 个答案:

答案 0 :(得分:0)

binary format formatString ?arg arg ...?link)是你的朋友。

  

binary format命令生成二进制字符串,其布局由formatString&gt;指定,其内容来自其他参数。返回结果二进制值。

在您的情况下,您将向二进制格式函数输入十六进制字符,因此您的formatString将是h *或H *,具体取决于您的MSB是最右边的字符(H *)还是最左边的字符(h *)

binary format H* 905082将返回包含原始数据0x905082的三个字节,即使字符串表示可能并不总是可打印。

将命令输出存储在一个变量中,你就可以了。

PS:另一种方法是检索要使用scan(link)解析的字符串的整数值。 scan $hexstring %x intvalue 和整数值将存储在$intvalue

答案 1 :(得分:0)

U + 905082不是Unicode字符。 Unicode规范明确声明限制为U + 10FFFF。它也不是单个字符的UTF-8编码(因为字节0x50总是以UTF-8编码单个字符,P)。所以无论你追求什么,它都不是一个单一的角色。

那么我们可以向我们开放什么?好吧,我们可以转换为字节序列:

set bytes [binary format H* "905082"]

嗯,就是这样!我们现在使用Unicode!现在,字节转换为与“\u0090\u0050\u0082”相同的字符序列。但也许你想要它们在特定的编码?那么,您可以使用encoding convertto来更改为不同的字节序列;

set bytesTurnedToUtf8 [encoding convertto utf-8 $bytes]

如果我们知道他们使用其他编码,我们可以使用encoding convertfrom进行反向操作。请注意,大多数时候你不需要花很多时间考虑Tcl中的编码; Tcl运行时为您管理字符串编码,您几乎不必考虑除字符序列之外的其他事项。