【问题标题】:Tcl for getting ASCII code for every character in a stringTcl 用于获取字符串中每个字符的 ASCII 码
【发布时间】:2010-12-13 03:19:21
【问题描述】:

我需要获取字符串中每个字符的 ASCII 字符。实际上它是一个(小)文件中的每个字符。以下前 3 行成功地将文件的所有内容拉入一个字符串(每个 this recipe):

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

我相信我可以正确识别字符的 ASCII 码(请参阅 http://wiki.tcl.tk/1497)。但是,我在弄清楚如何遍历字符串中的每个字符时遇到了问题。

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

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

代码:

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)"
}

输出:

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)

【问题讨论】:

  • 对TCL一无所知,但我可以从输出告诉你的是你的输入字符串是UTF-16,特别是UTF-16 little-endian,而不是ASCII。
  • Arthur,我很欣赏你的评论,但我很想知道,如何你能从输出中看出(它是 UTF-16 little-endian)吗?
  • UTF-16 使用两字节单元对字符进行编码。对于前 65536 个 Unicode 字符(所谓的平面 0),它使用其中一个单元,对于所有其余的,它使用两个(即 4 个字节,但区分为两个 代理字符 编码每个在两个字节上)。 ASCII 字符构成前 128 个 Unicode 字符,因此它们使用两个字节进行编码,最高有效位始终为 0,最低有效位等于字符的 ASCII 码。在这里,您会看到每个 ASCII 代码后跟一个空字节,因此您首先拥有最小顺序字节,即 UTF-16LE。
  • 感谢 Arthur,这比我在此期间查阅的 Wikipedia 文章更清楚!
  • 亚瑟,请考虑将其写成答案而不是评论,我肯定会赞成并可能接受它;这样您就可以为您的意见赢得一些声誉。

标签: string list ascii tcl utf-16


【解决方案1】:

以下代码应该可以工作:

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)?

【讨论】:

  • 我开始怀疑这可能是输入的问题,尽管每个字符之间没有空字符的充分理由,除非它是使用 Microsoft (SQL Server) 工具生成的;)
  • 那么这就是你的答案。大多数 Microsoft 工具(顺便说一下,Apple 的工具)都使用 UTF-16 作为其内部编码。 UTF-16LE 更为广泛,因为那是英特尔的原生字节序。您需要告诉 Tcl 将输入文件解释为 UTF-16。同样,不知道该怎么做,抱歉,但您应该在文档中查找诸如“编码”或“字符集”之类的关键字,或者一般来说,Unicode。
  • 想想你可能想做的事:fconfigure $fp -encoding unicode 在打开文件之后但在读取文件之前。
【解决方案2】:

在寻找其他东西时遇到了这个较老的问题。为了其他可能正在寻找这个问题答案的人的利益而回答这个问题。

首先,了解什么是字符编码。示例中的源数据不是 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") 使用 "encoding" 命令:

set data [encoding convertto utf-8 $data] ;# For UTF-8

set data [encoding convertto iso8859-1 $data] ;# For ISO 8859-1

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多