2009-11-04 351 views
7

我需要获取字符串中每个字符的ASCII字符。其实它在(小)文件中的每个字符。下面的前3行成功地拉了文件的所有内容到(每this recipe)的字符串:Tcl获取字符串中每个字符的ASCII码

set fp [open "store_order_create_ddl.sql" r] 
set data [read $fp] 
close $fp 

我相信我正确辨别的人物(见http://wiki.tcl.tk/1497)的ASCII码。不过,我在解决如何遍历字符串中的每个字符时遇到了问题。

首先,我不认为以下是使用Tcl在字符串中循环字符的一种特别惯用的方式。其次,更重要的是,它的行为不正确,在每个字符之间插入一个额外的元素。

下面是我写的代码,用于处理上面设置的“数据”变量的内容,后面跟着一些示例输出。

CODE:

for {set i 0} {$i < [string length $data]} {incr i} { 
    set char [string index $data $i] 
    scan $char %c ascii 
    puts "char: $char (ascii: $ascii)" 
} 

OUTPUT:

char: C (ascii: 67) 
char: (ascii: 0) 
char: R (ascii: 82) 
char: (ascii: 0) 
char: E (ascii: 69) 
char: (ascii: 0) 
char: A (ascii: 65) 
char: (ascii: 0) 
char: T (ascii: 84) 
char: (ascii: 0) 
char: E (ascii: 69) 
char: (ascii: 0) 
char: (ascii: 32) 
char: (ascii: 0) 
char: T (ascii: 84) 
char: (ascii: 0) 
char: A (ascii: 65) 
char: (ascii: 0) 
char: B (ascii: 66) 
char: (ascii: 0) 
char: L (ascii: 76) 
char: (ascii: 0) 
char: E (ascii: 69) 
+0

不知道TCL的任何内容,但是我可以从输出中告诉你输入字符串是UTF-16,特别是UTF-16小端,而不是ASCII。 – 2009-11-04 18:27:30

+0

Arthur,我很欣赏这个评论,但是我非常有兴趣知道,*你怎么能从输出中知道(它是UTF-16的小端)? – 2009-11-04 18:35:57

+1

UTF-16使用双字节单位对字符进行编码。对于第一个65536的Unicode字符(所谓的Plane 0),它使用其中一个单位,对于其余所有单位,它使用两个(即4个字节,但分为两个*替代字符*,每个字符编码为两个字节) 。 ASCII字符形成前128个Unicode字符,因此它们使用两个字节进行编码,最重要的字符总是0,最不重要的字符是ASCII码。在这里您会看到每个ASCII代码后跟一个空字节,因此您的第一个最低位字节即UTF-16LE。 – 2009-11-04 19:10:25

回答

9

下面的代码应该工作:

set data {CREATE TABLE} 
foreach char [split $data ""] { 
    lappend output [scan $char %c] 
} 
set output ;# 67 82 69 65 84 69 32 84 65 66 76 69 

至于在输出多余的字符,好像问题与来自文件的输入数据一起。有没有理由在文件中的每个字符之间会有空字符(\ 0)?

+0

我开始怀疑它可能是一个输入问题,虽然除了它是用微软(SQL Server)工具生成的,每个字符之间没有空字符的好理由;) – 2009-11-04 18:33:32

+0

那么这就是你的答案。大多数Microsoft工具(以及Apple的顺便说一下)都使用UTF-16作为其内部编码; UTF-16LE更为广泛,因为这是英特尔的本地排名。您需要告诉Tcl将输入文件解释为UTF-16。再次,不知道如何做到这一点,很抱歉,但您应该在文档中查找“编码”或“字符集”或一般来说Unicode的关键字。 – 2009-11-04 19:13:21

+0

想想你可能想要做的是:在打开文件之后但在读取文件之前,使用fconfigure $ fp -encoding unicode 。 – 2009-11-04 21:52:13

0

过这个旧的问题就来了,同时寻找其他的东西..要回答它为别人谁可能会寻找一个回答这个问题的好处..

首先,了解什么文字编码。 。示例中的源数据不是ASCII字符编码,因此ASCII字符代码(代码0-127)确实没有任何意义 - 除本例外,编码看起来是UTF-16,其中包括ASCII代码作为子集。你可能想要的是全部的“字符”代码,从0到255,但取决于你的系统,数据的来源等,代码128-255可能是ANSI,ISO或其他奇怪的代码页。你想要做的是将数据转换为你知道如何处理的格式,比如非常常见的ISO 8859-1代码(编码为“iso8859-1”),它非常类似于Windows 1252标准编码(编码“ CP1252" ),或UTF-8(编码 “UTF-8”)与 “编码” 命令:

组数据[编码的ConvertTo UTF-8 $数据];#对于UTF-8

组数据[encoding convertto iso8859-1 $ data];#For ISO 8859-1

等等。如果您正在读取文件中的数据,则可能还需要在读取数据之前设置文件编码(通过fconfigure),以确保正确读取文件数据。查看手册中的“编码”(和“fconfigure”)以获取更多有关处理字符集编码的详细信息。

一旦您控制了数据的编码,示例代码的其余部分应该按预期工作。