2010-05-05 106 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。確保編碼差異不會讓你失望。

相關問題