|
||
| [IT] Kylix, Libc.pas: operazioni sui codici numerici dei caratteri | ||
|
Kylix, Libc.pas: operazioni sui codici numerici dei caratteri 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
Per usare il codice procedere come segue:
//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:
//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.
|
||
(c) 1999-2006
|