2010-05-05 76 views
1

背景。我正在使用netlists,通常,人们使用/来指定不同的层次结构。但是,实际使用/作为实例名称的一部分并不违法。什么时候|不等于|?

例如,X1/X2/X3/X4可能指的是在名为X1/X2/X3的另一个实例内的实例X4。或者它可能引用名为X1的实例中名为X2的实例中名为X3/X4的实例。得到它了?

真的没有“常规”字符不能被用作一个实例名称的一部分,所以你再打一个不可打印的一个,或者......也许一个标准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范围以外的字符会像t他?当我将分隔符更改为(十进制)28(^\)时,情况正常。我只是不想在不同的平台上遇到类似的问题。 (我目前使用Redhat Linux)。

回答

4

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

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

您可以阅读更多关于TCL and UTF-8

+2

注:现代意味着“从8.1开始”,并且这种方式已经超过十年。此外,提问者正在寻找的函数是'Tcl_ExternalToUtfDString'。 – 2010-05-06 08:34:30

6

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

  • 124 |垂直线条
  • 166 |断条

一些旧字体混合了两个字形。

+0

对,问题是'[scan%c $ string]'返回166 ** ** Tcl和C++生成的字符。如果问题如你所述,'[scan%c |]'将返回124(不是166)。 – 2010-05-05 00:21:42

+0

@ dan04:我只能输入|从我的键盘[垂直线]。你是如何输入[broken bar]的? – Lazer 2010-05-12 09:50:15

+0

我使用了字符映射。 – dan04 2010-05-12 12:26:38

4

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

相关问题