2009-11-04 12 views
7

Ho bisogno di ottenere il carattere ASCII per ogni carattere in una stringa. In realtà ogni suo carattere in un (piccolo) file. Le seguenti prime 3 righe tirare con successo tutti i contenuti di un file in una stringa (per this recipe):Tcl per ottenere il codice ASCII per ogni carattere in una stringa

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

Credo che sto correttamente discernere il codice ASCII per i caratteri (vedi http://wiki.tcl.tk/1497). Tuttavia ho un problema a capire come eseguire il loop su ogni carattere nella stringa.

Prima di tutto non penso che quanto segue sia un modo particolarmente idiomatico di eseguire il looping dei caratteri in una stringa con Tcl. In secondo luogo, e soprattutto, si comporta in modo errato, inserendo un elemento in più tra ogni personaggio.

Di seguito è riportato il codice che ho scritto per agire sui contenuti della variabile "dati" impostata sopra, seguita da alcuni esempi di output.

CODICE:

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

USCITA:

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

Non so nulla di TCL, ma quello che posso dire dall'output è che la stringa di input è in UTF-16, in particolare UTF-16 little-endian, non ASCII. –

+0

Arthur, apprezzo il commento, ma sono molto interessato a sapere, * come * puoi dire che (è il piccolo-endian UTF-16) dall'output? –

+1

UTF-16 utilizza unità a due byte per codificare i caratteri. Per i primi 65536 caratteri Unicode (il cosiddetto Piano 0), usa una di quelle unità, per tutto il resto, usa due (cioè, 4 byte, ma si distingue in due * caratteri surrogati * codificati ciascuno su due byte) . I caratteri ASCII formano i primi 128 caratteri Unicode, quindi sono codificati usando due byte, il più significativo è sempre lo 0, il meno significativo uguale al codice ASCII del personaggio. Qui vedi che ogni codice ASCII è seguito da un byte nullo, quindi stai avendo il byte di ordine inferiore, cioè UTF-16LE. –

risposta

9

Il seguente codice dovrebbe funzionare:

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 

Per quanto riguarda i personaggi extra nella vostra uscita, sembra che il problema è con i tuoi dati di input dal file. C'è qualche ragione per cui ci sono caratteri null (\ 0) tra ogni carattere nel file?

+0

Avevo iniziato a sospettare che potesse essere un problema con l'input, sebbene non ci sia un buon motivo per i caratteri null tra ogni carattere, tranne che è stato generato con uno strumento Microsoft (SQL Server); –

+0

Quindi questa è la tua risposta . La maggior parte degli strumenti Microsoft (oltre a quelli di Apple), usa UTF-16 come codifica interna; UTF-16LE è molto più diffuso perché è il nativo Intel endianness. Devi dire a Tcl di interpretare il file di input come UTF-16. Ancora una volta, non ho idea di come farlo, mi dispiace, ma dovresti cercare parole chiave come "codifica" o "set di caratteri" o, in generale, Unicode, nei documenti. –

+0

Pensa che potresti voler fare: fconfigure $ fp -encoding unicode dopo aver aperto il file ma prima di leggerlo. –

0

sono imbattuto in questa domanda più vecchio mentre alla ricerca di qualcosa di diverso .. Andando a rispondere a beneficio di chiunque altro che possono essere alla ricerca di una risposta a questa domanda ..

Prima di tutto, capire che cosa codifica dei caratteri sono . I dati sorgente nell'esempio NON sono codifica caratteri ASCII, quindi i codici carattere ASCII (codici 0-127) non hanno alcun significato. Tranne in questo esempio, la codifica sembra essere UTF-16, che include i codici ASCII come sottoinsieme . Quello che probabilmente si desidera è l'intera gamma di codici "caratteri" da 0 a 255, ma a seconda del sistema, dell'origine dei dati, ecc., I codici 128-255 possono essere ANSI, ISO o qualche altra strana pagina di codice. Quello che vuoi fare è convertire i dati in un formato che sai come gestire, come il codice ISO 8859-1 molto comune (codifica "iso8859-1"), che è molto simile alla codifica standard di Windows 1252 (codifica " [codifica dei dati convertto UTF-8 $]

dati impostati; # Per i dati set UTF-8

: CP1252"), o UTF-8 (che codifica "UTF-8") con il "comando di codifica" [encoding convertto iso8859-1 $ data]; # Per ISO 8859-1

e così via. Se stai leggendo i dati da un file, potresti voler impostare la codifica del file (tramite fconfigure) prima di leggere anche i dati, per assicurarti di leggere correttamente i dati del file. Cerca le pagine man per "encoding" (e "fconfigure") per maggiori dettagli sulla consegna della codifica dei set di caratteri.

Una volta che la codifica dei dati è sotto controllo, il resto del codice di esempio dovrebbe funzionare come previsto.

Problemi correlati