Cloud with rain
.:G
G:.
0 and 1 serie, black on white
pulled card
myjsp.feelinglinux.com
ver. 1.1.9-4
Hallo, welcome to my world.
Here you can find some stuff about computer science.
<<< Enjoy your visit! >>>
0 and 1 serie, white on black

Kylix, Libc.pas: operazioni sui codici numerici dei caratteri

        Scritto: Giansante Gabriele, 2002     

Specialmente quando si ha a che fare con uno stream di dati, capita di leggere valori numerici (8 bit) da dover considerare come caratteri. Ad esempio, in valori decimali,
  "0" = 48
  "1" = 49
  "2" = 50 
  ...
  "A" = 65
  "B" = 66
  ...
In parte si tratta del set di caratteri ASCII (ricordo che il codice ASCII copre le combinazioni dei primi 7 bit di un carattere).

Per alcune manipolazioni, puo' essere utile verificare il tipo di carattere che si sta leggendo.
Ad esempio potremmo voler sapere se un particolare carattere e' uno spazio, un carattere numerico, un carattere alfabetico, un carattere stampabile, ecc.

In Libc.pas vengono dichiarate delle funzioni interessanti (vedere anche "/usr/include/ctype.h"), alcune di test ed altre di conversione, tutte soggette comunque al locale in uso sul sistema dove vengono usate (man locale, man setlocale):
  //Test
  function isalnum(c: integer):integer;
  function isalpha(c: integer):integer;
  function isdigit(c: integer):integer;
  function isxdigit(c: integer):integer;
  function islower(c: integer):integer;
  function isupper(c: integer):integer;
  function isblank(c: integer):integer;
  function isascii(c: integer):integer;
  function isspace(c: integer):integer;
  function iscntrl(c: integer):integer;
  function isgraph(c: integer):integer;
  function isprint(c: integer):integer;
  function ispunct(c: integer):integer;

  //Conversione
  function toascii(c: integer):integer;
  function tolower(c: integer):integer;
  function toupper(c: integer):integer;
Dalle dichiarazioni mostrate, risulta evidente come queste funzioni lavorino tutte a livello di codice intero del carattere.
Le funzioni di conversione restituiscono tutte il codice del carattere modificato.
Le funzioni di test, invece, restituiscono il valore 0 se il test fallisce, un valore diverso da zero se il carattere rientra nel tipo richiesto.

Funzioni di conversione
  • toascii converte il carattere passato in carattere ASCII, cioe' elimina il bit di ordine piu' alto azzerandolo. Es. 10011101 -> 00011101. In pratica e' una forzatura piu' che una conversione.
  • tolower trasforma il carattere passato da maiuscolo a minuscolo, ovviamente solo per i caratteri per cui la conversione e' applicabile. Come tutte le altre funzioni, questa conversione dipende dalle impostazioni locali (nazioni diverse hanno set di caratteri diversi). Es. A->a.
  • toupper funziona come tolowerm ma trasforma da minuscolo a maiuscolo.
Funzioni di test
  • isalnum verifica che il carattere passato sia alfanumerico (alfabetico o numerico).
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isalpha verifica che il carattere passato sia alfabetico.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isdigit verifica che il carattere passato sia un carattere numerico (0..9).
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isxdigit verifica che il carattere rappresenti una cifra esadecimale (0...9, a...f, A...F). Vengono riconosciute sia le cifre minuscole che le maiuscole.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • islower verifica che il carattere passato sia minuscolo. Questa funzione e' fortemente dipendente dalle impostazioni locali.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isupper e' come is lower ma verifica la presenza di caratteri maiuscoli.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isblank verifica che il carattere passato sia uno spazio o un "tab" (tabulazione).
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isascii verifica che il carattere passato appartenga al set di caratteri ASCII.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isspace determina se il carattere e' uno spazio, ovvero uno dei seguenti:
    #20 (spazio normale),
    #0C (form-feed, "\f" in c),
    #0A (nuova linea, "\n" in c),
    #0D (ritorno di carrello, "\r" in c),
    #09 (tab orizzontale, "\t" in c),
    #0B (tab verticale, "\v" in c).
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • iscntrl verifica che il carattere passato sia un carattere di controllo.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isgraph verifica che il carattere passato sia stampabile, Non viene preso in considerazione lo spazio.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • isprint e' identica a isgraph, ma include lo spazio.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
  • ispunct verifica che il carattere passato sia un carattere stampabile. Non vengono presi in considerazione i caratteri alfanumerici e lo spazio.
    Il valore restituito e' 0 se il carattere non e' del tipo richiesto, diverso da zero se e' del tipo giusto.
Da quanto visto le funzioni sono tante e semplici da usare. Puo' essere utile vedere un esempio di queste funzioni all'opera. Il seguente codice (uso didattico, non ottimizzato) serve a visualizzare le statistiche sul tipo di caratteri presenti in un file; e' un esempio di utilizzo delle funzioni di test.
Per usare il codice procedere come segue:
  • Creare un nuovo progetto come console application (File->New...->Console Application). Tipicamente avra' il nome "Project1".
  • Al posto del sorgente visualizzato, copiare quello mostrato.
  • Modificare il nome del file con uno su cui si vogliono effettuare statistiche.
  • Salvare tutto.
  • Compilare il progetto (Project->Build Project1).
  • Da una shell posizionarsi nella directory dove sono stati salvati i file ed eseguire il comando "./Project1".
//Project1.dpr
//------------

{
   Programma di esempio. Vengono effettuate statistiche sul
   tipo di caratteri presenti in un file.

   Linux&Me - http://www.feelinglinux.com

   Giansante Gabriele (c) 2002
}

program statistiche_caratteri;

{$APPTYPE CONSOLE}

uses
  Classes,SysUtils, Libc;

var
  //Stream da cui leggere i caratteri
  stream: TFileStream;
  //Codice del carattere letto di volta in volta.
  codice: byte;
  //Nome del file da leggere
  nomefile: String;

  //STATISTICA

    alfabetici: Int64;
    numerici: Int64;
    alfanumerici: Int64;
    esadecimali: Int64;
    minuscoli: Int64;
    maiuscoli: Int64;
    //Spazio,tab
    blank: Int64;
    ascii: Int64;
    //spazi, FF, LF, CR, HT, VT
    spazi: Int64;
    controllo: Int64;

begin
  //Modificare il nome del file con uno esistente ed accessibile
  nomefile := '/tmp/prova.txt';

  stream := nil;

  alfabetici := 0;
  numerici := 0;
  alfanumerici := 0;
  esadecimali := 0;
  minuscoli := 0;
  maiuscoli := 0;
  blank := 0;
  ascii := 0;
  spazi := 0;
  controllo := 0;

  //Potrebbe essere impossibile aprire il file (es. se non esiste),
  //quindi viene racchiuso il tutto in un blocco try...except.
  try
    //Apertura del file in sola lettura
    stream := TFileStream.Create(nomefile,fmOpenRead);
    //Finche' riesco a leggere un carattere (risultato di read=1),
    //aggiorno le statistiche.
    while (stream.Read(codice,1)=1) do begin
      if isalnum(codice)<>0 then alfanumerici := alfanumerici + 1;
      if isalpha(codice)<>0 then alfabetici := alfabetici + 1;
      if isdigit(codice)<>0 then numerici := numerici + 1;
      if isxdigit(codice)<>0 then esadecimali := esadecimali + 1;
      if islower(codice)<>0 then minuscoli := minuscoli + 1;
      if isupper(codice)<>0 then maiuscoli := maiuscoli + 1;
      if isblank(codice)<>0 then blank := blank + 1;
      if isascii(codice)<>0 then ascii := ascii + 1;
      if isspace(codice)<>0 then spazi := spazi + 1;
      if iscntrl(codice)<>0 then controllo := controllo + 1;
    end;

    //Esposizione del risultato.
    writeln('Alfabetici: '+IntToStr(alfabetici));
    writeln('Numerici: '+IntToStr(numerici));
    writeln('Alfanumerici: '+IntToStr(alfanumerici));
    //Attenzione, vengono considerati come cifre esadecimali anche 
    //i caratteri all'interno di una normale parola (es. nella parola 
    //"ciao", i caratteri "c" ed "a" sono anche cifre esadecimali)
    writeln('Esadecimali: '+IntToStr(esadecimali));
    writeln('Maiuscoli: '+IntToStr(maiuscoli));
    writeln('Minuscoli: '+IntToStr(minuscoli));
    writeln('Blank: '+IntToStr(blank));
    writeln('ASCII: '+IntToStr(ascii));
    writeln('Spazi: '+IntToStr(spazi));
    writeln('Controllo: '+IntToStr(controllo));
  except
    //Se si entra qui, tipicamente  il file non esiste o
    //si potrebbe non avere il permesso di leggerlo
    on EFOpenError do writeln('Impossibile aprire il file');
  end;
  if stream<>nil then stream.Free;
end.
Il seguente codice (uso didattico, non ottimizzato) serve a copiare un file in un'altro con i caratteri del primo trasformati in minuscolo (esempio 1), maiuscolo (esempio 2), codice ASCII (esempio 3); e' un esempio di utilizzo delle funzioni di conversione.
Per usare il codice procedere come segue:
  • Creare un nuovo progetto come console application (File->New...->Console Application). Tipicamente avra' il nome "Project2" se non si e' chiuso il Project1.
  • Al posto del sorgente visualizzato, copiare quello mostrato.
  • Per attivare un esempio particolare, eliminare i commenti relativi.
  • Modificare i nomi dei file di input e di output con altri a piacere (quello di input deve esistere, quello di output verra' sovrascritto).
  • Salvare tutto.
  • Compilare il progetto (Project->Build Project2).
  • Da una shell posizionarsi nella directory dove sono stati salvati i file ed eseguire il comando "./Project2".
  • Per verificare il risultato, confrontare il file di input con quello di output. Notare che il file di output, nel caso dell'esempio 3 (conversione in ASCII) potrebbe non presentare differenze se si tratta di un file con solo caratteri aventi codice inferiore o uguale a 127 (codifica 7 bit). Il risultato dell'esempio 3 e' fortemente dipendente dal set di caratteri usato.
//Project2.dpr
//------------

{
   Programma di esempio. Vengono mostrati tre esempi di conversione
   di un file: in minuscolo, maiuscolo, ASCII.

   Linux&Me - http://www.feelinglinux.com

   Giansante Gabriele (c) 2002
}

program statistiche_caratteri;

{$APPTYPE CONSOLE}

uses
  Classes,
  SysUtils,
  Libc;

var
  //Stream da cui leggere i caratteri
  streamin: TFileStream;
  //Stream in cui scrivere i caratteri
  streamout: TFileStream;
  //Codice del carattere letto/scritto di volta in volta.
  codice: byte;
  //Contiene il codice trasformato
  nuovocodice: integer;
  //Nome del file da leggere
  nomefilein: String;
  //Nome del file da scrivere
  nomefileout: String;

begin
  //Modificare il nome del file con uno esistente ed accessibile
  nomefilein := '/tmp/provain.txt';
  //Modificare il nome del file con uno non esistente in una
  //directory accessibile
  nomefileout := '/tmp/provaout.txt';

  streamin := nil;
  streamout := nil;

  //Potrebbe essere impossibile aprire il file (es. se non esiste),
  //quindi viene racchiuso il tutto in un blocco try...except.
  try
    //Apertura del file di input in lettura
    streamin := TFileStream.Create(nomefilein,fmOpenRead);
    //Creazione del file di output (scrittura)
    streamout := TFileStream.Create(nomefileout,fmCreate);
    //Finche' riesco a leggere un carattere (risultato di read=1),
    //effettuo la conversione.
    while (streamin.Read(codice,1)=1) do begin
      //Esempio 1
      //---------
      //Conversione in minuscolo. Levare il commento per
      //attivare questo esempio, commentare per disabilitarlo.

      nuovocodice := tolower(codice);
      streamout.Write(nuovocodice,1);

      //Esempio 2
      //---------
      //Conversione in maiuscolo. Levare il commento per
      //attivare questo esempio, commentare per disabilitarlo.

      //nuovocodice := toupper(codice);
      //streamout.Write(nuovocodice,1);

      //Esempio 3
      //---------
      //Conversione in carattere ASCII. Levare il commento per
      //attivare questo esempio, commentare per disabilitarlo.

      //nuovocodice := toascii(codice);
      //streamout.Write(nuovocodice,1);
      
      //---
      //Levare il commento alla linea che segue per verificare il codice del carattere letto. 
      //Utile soprattutto per la verifica di "toascii", farlo solo per file lunghi pochi byte.
      //writeln(codice);
    end;

  except
    //Se si entra qui, tipicamente  il file non esiste o
    //si potrebbe non avere il permesso di leggerlo
    on EFOpenError do writeln('Impossibile aprire/creare il file');
  end;
  if streamin<>nil then streamin.Free;
  if streamout<>nil then streamout.Free;
end.


Hai trovato utile questo articolo?
Aiutami a condividerlo o metti un "mi piace".
Grazie mille!


Gli strumenti di condivisione (Google+, Facebook) sono visibili in alto a destra solo dopo aver accettato la policy di utilizzo dei cookie per questo sito.
FAQ - Come faccio a cambiare la mia scelta?

 

Strumenti (myjsp.feelinglinux.com)
Gioco: allenamento con la tastiera Strumenti di codifica/decodifica URI (%-encoding) e Base64 Strumenti di calcolo online per IP e Reti
QUIZ GAME
Quiz game

Cerca @myjsp.feelinglinux.com

Pubblicita'