什么时候|不等于|?

时间:2010-05-05 00:06:39

标签: c++ c ascii tcl

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

例如,X1/X2/X3/X4可能在另一个名为X4的实例中引用实例X1/X2/X3。或者它可能在名为X3/X4的实例中的名为X2的实例中引用名为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。)

3 个答案:

答案 0 :(得分:6)

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

  • 124 |垂直线
  • 166 | BROKEN BAR

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

答案 1 :(得分:4)

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

答案 2 :(得分:4)

据我了解,现代版本的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的更多信息。