2009-11-04 9 views
7

Necesito obtener el carácter ASCII para cada carácter de una cadena. En realidad, es cada personaje en un archivo (pequeño). Los siguientes 3 primeras líneas de tracción con éxito todos los contenidos de un archivo en una cadena (por this recipe):Tcl para obtener el código ASCII para cada carácter en una cadena

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

Creo que estoy discerniendo correctamente el código ASCII de los caracteres (consulte http://wiki.tcl.tk/1497). Sin embargo, tengo un problema para encontrar la forma de recorrer todos los caracteres de la cadena.

En primer lugar, no creo que la siguiente es una forma especialmente idiomática de reproducir los caracteres en una cadena con Tcl. En segundo lugar y más importante, se comporta de manera incorrecta, insertando un elemento extra entre cada personaje.

A continuación se muestra el código que he escrito para actuar sobre los contenidos de la variable "datos" configurados anteriormente, seguidos de algunos ejemplos de salida.

CÓDIGO:

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

SALIDA:

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

No sé nada sobre TCL, pero lo que puedo decir de la salida es que su cadena de entrada está en UTF-16, específicamente UTF-16 little-endian, no ASCII. –

+0

Arthur, agradezco el comentario, pero estoy muy interesado en saber, * ¿cómo puedes decir eso (es UTF-16 little-endian) de la salida? –

+1

UTF-16 usa unidades de dos bytes para codificar caracteres. Para los primeros 65536 caracteres Unicode (el denominado Plano 0), usa una de esas unidades, para el resto, usa dos (es decir, 4 bytes, pero se distinguen en dos * caracteres sustituidos * codificados cada uno en dos bytes) . Los caracteres ASCII forman los primeros 128 caracteres Unicode, por lo tanto, están codificados con dos bytes, siendo el más significativo siempre 0, el menos significativo igual al código ASCII del personaje. Aquí puede ver que a cada código ASCII le sigue un byte nulo, por lo tanto, primero tiene byte de orden mínimo, es decir, UTF-16LE. –

Respuesta

9

El siguiente código debería funcionar:

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 

En cuanto a los caracteres adicionales en su salida, parece que el problema es con sus datos de entrada desde el archivo. ¿Hay alguna razón para que haya caracteres nulos (\ 0) entre cada carácter en el archivo?

+0

Empecé a sospechar que podría ser un problema con la entrada, aunque no hay una buena razón para caracteres nulos entre cada carácter, excepto que se generó con una herramienta de Microsoft (SQL Server);) –

+0

Entonces esa es su respuesta . La mayoría de las herramientas de Microsoft (así como las de Apple, por cierto) usan UTF-16 como su codificación interna; UTF-16LE está mucho más extendido porque ese es el endianness nativo de Intel. Necesita decirle a Tcl que interprete el archivo de entrada como UTF-16. De nuevo, no tengo idea de cómo hacerlo, lo siento, pero debería buscar palabras clave como "codificación" o "juego de caracteres" o, en términos generales, Unicode, en los documentos. –

+0

Piensa que quizás quieras hacer: fconfigure $ fp -encoding unicode después de abrir el archivo pero antes de leerlo. –

0

encontré con esta pregunta más antigua en la búsqueda de algo más .. va a responder por el beneficio de cualquier otra persona que pueda estar buscando una respuesta a esta pregunta ..

En primer lugar, entender lo que son las codificaciones de caracteres . La fuente de datos en el ejemplo NO es la codificación de caracteres ASCII, por lo que los códigos de caracteres ASCII (códigos 0-127) realmente no tienen ningún significado. Excepto en este ejemplo, la codificación parece ser UTF-16, que incluye códigos ASCII como un subconjunto . Lo que probablemente desee es la gama completa de códigos de "caracteres" de 0 a 255, pero según el sistema, la fuente de los datos, etc., los códigos 128-255 pueden ser ANSI, ISO o alguna otra página de códigos extraña. Lo que quiere hacer es convertir los datos en un formato que sepa cómo manejar, como el muy común código ISO 8859-1 (que codifica "iso8859-1"), que es muy similar a la codificación estándar de Windows 1252 (codificación " [codificación de datos ConvertTo UTF-8 $]

datos de conjunto; # Para los datos de conjunto UTF-8

: CP1252"), o UTF-8 (que codifica "UTF-8") con el "comando de codificación" [codificación convertto iso8859-1 $ datos]; # Para ISO 8859-1

y así sucesivamente. Si está leyendo los datos de un archivo, es posible que desee establecer la codificación del archivo (a través de fconfigure) antes de leer los datos, para asegurarse de que está leyendo correctamente los datos del archivo. Consulte las páginas man para "codificar" (y "fconfigure") para obtener más detalles sobre la entrega de la codificación del juego de caracteres.

Una vez que tenga la codificación de los datos bajo control, el resto del código de ejemplo debería funcionar como se esperaba.

Cuestiones relacionadas