【问题标题】:When is ¦ not equal to ¦?¦ 什么时候不等于 ¦?
【发布时间】:2010-05-05 00:06:38
【问题描述】:

背景。我正在使用netlists,一般来说,人们使用/ 指定不同的层次结构。但是,实际使用 / 作为实例名称的一部分并不违法。

例如,X1/X2/X3/X4 可能在另一个名为 X1/X2/X3 的实例中引用实例 X4。或者它可能会在名为X2 的实例中引用名为X3/X4 的实例,该实例位于名为X1 的实例中。明白了吗?

确实没有“常规”字符不能用作实例名称的一部分,因此您可以使用不可打印的字符,或者......也许是标准 0 之外的字符..127 ASCII 字符。

我想我会尝试(十进制)166,因为对我来说它显示为管道:¦

所以...我有一些 C++ 代码使用 ¦ 作为分层分隔符构造路径名,所以上面的路径看起来像 X1¦X2/X3¦X4

现在 GUI 是用 Tcl/Tk 编写的,为了正确地将其翻译成人类可读的术语,我需要执行以下操作:

set path [getPathFromC++] ;# returns X1¦X2/X3¦X4
set humanreadable [join [split $path ¦] /]

基本上,将¦ 替换为/(我也可以使用[string map] 完成此操作)。

现在,问题是,我从 C++ 获得的字符串中的 ¦ 与我可以在 Tcl 中创建的 ¦ 不匹配。即这失败了:

set path [getPathFromC++] ;# returns X1¦X2/X3¦X4
string match $path [format X1%cX2/X3%cX4 166 166]

在视觉上,这两个字符串看起来相同,但字符串匹配失败。我什至尝试使用scan 来查看我是否混淆了位值。但是

set path [getPathFromC++] ;# returns X1¦X2/X3¦X4
set path2 [format X1%cX2/X3%cX4 166 166]
for {set i 0} {$i < [string length $path]} {incr i} {
   set p [string range $path $i $i]
   set p2 [string range $path2 $i $i]
   scan %c $p c
   scan %c $p2 c2
   puts [list $p $c :::: $p2 $c2 equal? [string equal $c $c2]]
}

产生看起来所有内容都应该匹配的输出,除了 [string equal] 对带有打印行的 ¦ 字符失败:

¦ 166 :::: ¦ 166 equal? 0

不管怎样,C++中的字符定义为:

const char SEPARATOR = 166;

知道为什么常规 ASCII 范围之外的字符会像这样失败吗?当我将分隔符更改为(十进制)28(^\)时,一切正常。我只是不想在不同的平台上遇到类似的问题。 (我目前正在使用 Redhat Linux)。

【问题讨论】:

    标签: c++ c ascii tcl


    【解决方案1】:

    Latin-1 有两个不同的vertical bar 字符:

    • 124 |垂直线
    • 166 ¦ 断杆

    一些较旧的字体混淆了这两种字形。

    【讨论】:

    • 对,问题是[scan %c $string] 我的 Tcl 和 C++ 生成的字符返回 166。如果问题如您所述,[scan %c |] 将返回 124(不是 166)。
    • @dan04:我只能输入 | [垂直线]来自我的键盘。你是怎么输入[断条]的?
    【解决方案2】:

    据我了解,现代版本的 TCL 在内部使用 UTF-8 来表示字符串。在 UTF-8 中,十进制 166 是一个字符的一半,所以难怪所有的地狱都崩溃了。 ;-)

    我的猜测是您的 C++ 代码使用的是 Latin-1 字符串(即char *),而您将其传递给 TCL,TCL 将其解释为 UTF-8 字符串。在将 C++ 字符串传递给任何 TCL C 函数之前,您需要将其转换为 UTF-8。 TCL提供some functions for this purpose

    你可以阅读更多关于TCL and UTF-8的信息。

    【讨论】:

    • 注意:Modern 的意思是“从 8.1 开始”,并且十多年来一直如此。此外,提问者正在寻找的功能是Tcl_ExternalToUtfDString
    【解决方案3】:

    在我的系统上,tcl 脚本puts [format %c 166] 以 UTF-8 ("\xC2\xA6") 输出,而 C++ 语句 cout &lt;&lt; "\xA6"; 输出 Latin-1。确保编码差异不会让您失望。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 2016-06-26
      • 2017-08-11
      相关资源
      最近更新 更多