2010-05-05 4 views
1

Фон. Я работаю с 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++ определен as:

const char SEPARATOR = 166; 

Любые идеи, почему персонаж вне регулярного диапазона ASCII потерпит неудачу, как t его? Когда я сменил разделитель на (десятичный) 28 (^\), все сработало нормально. Я просто не хочу, чтобы бит по аналогичной проблеме на другой платформе. (В настоящее время я использую Redhat Linux).

ответ

4

Как я понимаю, современные версии TCL используют UTF-8 для представления строк. В UTF-8 десятичная цифра 166 равна половине персонажа, поэтому неудивительно, что весь ад разрывается. ;-)

Я предполагаю, что ваш код на C++ использует строку Latin-1 (т. Е. char *), и вы передаете это в TCL, который интерпретирует его как строку UTF-8. Вам нужно преобразовать вашу C++-строку в UTF-8, прежде чем передавать ее на любые функции TCL C. TCL обеспечивает some functions for this purpose.

Вы можете узнать больше о TCL and UTF-8.

+2

NB: Современное означает «с 8.1 года» и было таким образом уже более десяти лет. Кроме того, функция, которую интересует вопросик, это 'Tcl_ExternalToUtfDString'. –

6

Latin-1 имеет два различных vertical bar символы:

  • 124 | ВЕРТИКАЛЬНАЯ ЛИНИЯ
  • 166 | СЛОМЛЕННЫЙ BAR

Некоторые старые шрифты перепутал два глифы.

+0

Правильно, проблема заключается в том, что '[scan% c $ string]' возвращает 166 для ** обоих ** моих Tcl и C++ сгенерированных символов. Если проблема была такой, как вы описали, '[scan% c |]' вернет 124 (не 166). –

+0

@ dan04: я могу только напечатать | [вертикальная линия] с моей клавиатуры. Как вы набрали [сломанный бар]? – Lazer

+0

Я использовал Карту символов. – dan04

4

В моей системе сценарий tcl puts [format %c 166] выводит в UTF-8 ("\ xC2 \ xA6"), в то время как оператор C++ cout << "\xA6"; выводит Latin-1. Убедитесь, что различия в кодировке не отбрасывают вас.

Смежные вопросы