Successivo: , Precedente: , Su: Funzioni di tipo generale   [Contenuti][Indice]


10.2.5 Tradurre tra caratteri e numeri

Un’implementazione commerciale di awk fornisce una funzione predefinita ord(), che prende un carattere e restituisce il valore numerico per quel carattere nella rappresentazione dei caratteri di quella particolare macchina. Se la stringa passata a ord() ha più di un carattere, viene usato solo il primo.

L’inverso di questa funzione è chr() (dalla funzione con lo stesso nome in Pascal), che, dato un numero, restituisce il corrispondente carattere. Entrambe le funzioni si possono scrivere molto bene usando awk; non vi è nessun reale motivo per inglobarle come funzioni predefinite awk:

# ord.awk --- implementa ord e chr

# Identificativi globali:
#    _ord_:        valori numerici indicizzati da caratteri
#    _ord_init:    funzione per inizializzare _ord_

BEGIN    { _ord_init() }

function _ord_init(    basso, alto, i, t)
{
    basso = sprintf("%c", 7) # BEL è ascii 7
    if (basso == "\a") {     # ascii regolare
        basso = 0
        alto = 127
    } else if (sprintf("%c", 128 + 7) == "\a") {
        # ascii, con il primo bit a 1 (mark)
        basso = 128
        alto = 255
    } else {        # ebcdic(!)
        basso = 0
        alto = 255
    }

    for (i = basso; i <= alto; i++) {
        t = sprintf("%c", i)
        _ord_[t] = i
    }
}

Alcune spiegazioni riguardo ai numeri usati da _ord_init() non guastano. La serie di caratteri più importante oggi in uso è nota come ASCII.70 Sebbene un byte a 8 bit possa contenere 256 valori distinti (da 0 a 255), ASCII definisce solo i caratteri che usano i valori da 0 a 127.71 Nel lontano passato, almeno un produttore di microcomputer ha usato ASCII, ma con una parità di tipo mark, cioè con il bit più a sinistra sempre a 1. Questo significa che su questi sistemi i caratteri ASCII hanno valori numerici da 128 a 255. Infine, i grandi elaboratori centrali usano la serie di caratteri EBCDIC, che prevede tutti i 256 valori. Ci sono altre serie di caratteri in uso su alcuni sistemi più vecchi, ma non vale la pena di considerarli:

function ord(str,    c)
{
    # solo il primo carattere è d'interesse
    c = substr(str, 1, 1)
    return _ord_[c]
}

function chr(c)
{
    # trasforma c in un numero aggiungendo uno 0
    return sprintf("%c", c + 0)
}

#### programma di verifica ####
# BEGIN {
#    for (;;) {
#        printf("immetti un carattere: ")
#        if (getline var <= 0)
#            break
#        printf("ord(%s) = %d\n", var, ord(var))
#    }
# }

Un ovvio miglioramento a queste funzioni è quello di spostare il codice per la funzione _ord_init nel corpo della regola BEGIN. Il programma è stato scritto inizialmente in questo modo per comodità di sviluppo. C’è un “programma di verifica” in una regola BEGIN, per verificare la funzione. È commentato, per poter essere eventualmente usato in produzione.


Note a piè di pagina

(70)

La situazione sta però cambiando: molti sistemi usano Unicode, una serie di caratteri molto ampia che comprende ASCII al suo interno. Nei sistemi che supportano interamente Unicode, un carattere può occupare fino a 32 bit, facendo diventare i semplici test usati qui eccessivamente complessi.

(71)

ASCII è stato esteso in molti paesi per usare i valori da 128 a 255 includendo i caratteri specifici del paese. Se il sistema in uso si avvale di queste estensioni, si può semplificare _ord_init() per eseguire un ciclo da 0 a 255.


Successivo: , Precedente: , Su: Funzioni di tipo generale   [Contenuti][Indice]