(* LIB_FILTRI.PAS *) (* Funzioni per il riconoscimento di stringhe particolari *) (* e per il filtraggio dei dati in ingresso. *) (* *) (* Autore: Corrado Damiano *) (* Data ultima versione: 24-8-2026 *) unit lib_filtri; (*--------------------------------*) INTERFACE uses sysutils; type p_longint = ^longint; p_byte = ^byte; (* funzioni generiche *) function ok_cifra(c: char): boolean; function ok_lettera_ascii(c: char): boolean; function ok_alfanum(c: char): boolean; function ok_sottostr_cifre(s: string; i_inizio: longint; i_fine: longint): boolean; function ok_sottostr_lettere(s: string; i_inizio: longint; i_fine: longint): boolean; function ok_sottostr_alfanum(s: string; i_inizio: longint; i_fine: longint): boolean; function ok_sottostr_char(s: string; c: char; i_inizio: longint; i_fine: longint): boolean; (* funzioni per stringhe che rappresentano numeri *) function ok_segno_inizio(s: string): boolean; function ok_numero(s: string): boolean; function togli_segno_inizio(s: string): string; function togli_zeri_inizio(s: string): string; function ok_str_longint(s: string; p_num: p_longint): boolean; function leggi_longint(s: string): longint; function ok_str_byte(s: string; p_num: p_byte): boolean; function leggi_byte(s: string): byte; (*--------------------------------*) IMPLEMENTATION (* funzioni generiche *) (* verifica se il carattere di input e' una cifra *) function ok_cifra(c: char): boolean; begin (* i numeri 48...57 sono i codici ASCII delle cifre 0...9 *) if ((ord(c) >= 48) and (ord(c) <= 57)) then begin ok_cifra := true; exit; end; ok_cifra := false; end; (* fine ok_cifra *) (* verifica se il carattere di input e' una lettera ASCII *) function ok_lettera_ascii(c: char): boolean; begin (* codici ASCII lettere maiuscole *) if ((ord(c) >= 65) and (ord(c) <= 90)) then begin ok_lettera_ascii := true; exit; end; (* codici ASCII lettere minuscole *) if ((ord(c) >= 97) and (ord(c) <= 122)) then begin ok_lettera_ascii := true; exit; end; ok_lettera_ascii := false; end; (* fine ok_lettera_ascii *) (* verifica se il carattere di input e' una lettera ASCII o una cifra *) function ok_alfanum(c: char): boolean; begin if ((ok_cifra(c) = true) or (ok_lettera_ascii(c) = true)) then begin ok_alfanum := true; exit; end; ok_alfanum := false; end; (* ok_alfanum *) (* data una stringa, verifica se la sottostringa individuata *) (* dagli indici di input e' formata solo da cifre *) function ok_sottostr_cifre(s: string; i_inizio: longint; i_fine: longint): boolean; var ok: boolean; lungh_s: longint; i: longint; c: char; begin ok := false; lungh_s := length(s); if lungh_s = 0 then begin ok_sottostr_cifre := ok; exit; end; (* gli indici di inizio/fine non possono puntare al di fuori della stringa *) (* e quello di inizio non puo' essere maggiore di quello di fine *) if ((i_inizio < 1) or (i_fine > lungh_s) or (i_inizio > i_fine)) then begin ok_sottostr_cifre := ok; exit; end; ok := true; for i := i_inizio to i_fine do begin c := s[i]; if ok_cifra(c) = false then begin ok := false; break; end; end; ok_sottostr_cifre := ok; end; (* fine ok_sottostr_cifre *) (* data una stringa, verifica se la sottostringa individuata *) (* dagli indici di input e' formata solo da lettere ASCII *) function ok_sottostr_lettere(s: string; i_inizio: longint; i_fine: longint): boolean; var ok: boolean; lungh_s: longint; i: longint; c: char; begin ok := false; lungh_s := length(s); if lungh_s = 0 then begin ok_sottostr_lettere := ok; exit; end; (* gli indici di inizio/fine non possono puntare al di fuori della stringa *) (* e quello di inizio non puo' essere maggiore di quello di fine *) if ((i_inizio < 1) or (i_fine > lungh_s) or (i_inizio > i_fine)) then begin ok_sottostr_lettere := ok; exit; end; ok := true; for i := i_inizio to i_fine do begin c := s[i]; if ok_lettera_ascii(c) = false then begin ok := false; break; end; end; ok_sottostr_lettere := ok; end; (* fine ok_sottostr_lettere *) (* data una stringa, verifica se la sottostringa individuata *) (* dagli indici di input e' formata solo da cifre *) (* o da lettere ASCII *) function ok_sottostr_alfanum(s: string; i_inizio: longint; i_fine: longint): boolean; var ok: boolean; lungh_s: longint; i: longint; c: char; begin ok := false; lungh_s := length(s); if lungh_s = 0 then begin ok_sottostr_alfanum := ok; exit; end; (* gli indici di inizio/fine non possono puntare al di fuori della stringa *) (* e quello di inizio non puo' essere maggiore di quello di fine *) if ((i_inizio < 1) or (i_fine > lungh_s) or (i_inizio > i_fine)) then begin ok_sottostr_alfanum := ok; exit; end; ok := true; for i := i_inizio to i_fine do begin c := s[i]; if ok_alfanum(c) = false then begin ok := false; break; end; end; ok_sottostr_alfanum := ok; end; (* fine ok_sottostr_alfanum *) (* data una stringa, verifica se la sottostringa individuata *) (* dagli indici di input contiene solo il carattere c *) function ok_sottostr_char(s: string; c: char; i_inizio: longint; i_fine: longint): boolean; var ok: boolean; lungh_s: longint; i: longint; begin ok := false; lungh_s := length(s); if lungh_s = 0 then begin ok_sottostr_char := ok; exit; end; (* gli indici di inizio/fine non possono puntare al di fuori della stringa *) (* e quello di inizio non puo' essere maggiore di quello di fine *) if ((i_inizio < 1) or (i_fine > lungh_s) or (i_inizio > i_fine)) then begin ok_sottostr_char := ok; exit; end; ok := true; for i := i_inizio to i_fine do begin if s[i] <> c then begin ok := false; break; end; end; ok_sottostr_char := ok; end; (* fine ok_sottostr_char *) (*--------------------------------*) (* funzioni per stringhe che rappresentano numeri *) (* verifica se il primo carattere della stringa di input *) (* e' il segno + oppure il segno - *) function ok_segno_inizio(s: string): boolean; begin if length(s) = 0 then begin ok_segno_inizio := false; exit; end; if ((s[1] = '+') or (s[1] = '-')) then begin ok_segno_inizio := true; exit; end; ok_segno_inizio := false; end; (* fine ok_segno_inizio *) (* verifica se la stringa di input puo' essere considerata un numero *) (* intero, con o senza segno *) function ok_numero(s: string): boolean; var lungh_s: longint; begin lungh_s := length(s); if lungh_s = 0 then begin ok_numero := false; exit; end; if ok_segno_inizio(s) = true then begin (* una stringa-numero con segno deve avere almeno due caratteri *) if lungh_s < 2 then begin ok_numero := false; exit; end; if ok_sottostr_cifre(s, 2, lungh_s) = false then begin ok_numero := false; exit; end; ok_numero := true; exit; end; (* stringa-numero senza segno *) if ok_sottostr_cifre(s, 1, lungh_s) = false then begin ok_numero := false; exit; end; ok_numero := true; end; (* fine ok_numero *) (* riceve in input una stringa che rappresenta un numero, *) (* con o senza segno + - iniziale; se la stringa ha il segno, *) (* rende in uscita una stringa con le stesse cifre, ma senza *) (* segno; in tutti gli altri casi passa in uscita una stringa *) (* uguale a quella di input *) function togli_segno_inizio(s: string): string; var s_nuova: string; lungh_s: longint; i: longint; c: char; begin s_nuova := ''; if ok_numero(s) = false then begin togli_segno_inizio := s; exit; end; lungh_s := length(s); (* se la stringa ha un solo carattere, questo e' una cifra *) (* e non c'e' segno da togliere *) if lungh_s = 1 then begin togli_segno_inizio := s; exit; end; (* stringa-numero senza segno *) if ((s[1] <> '+') and (s[1] <> '-')) then begin togli_segno_inizio := s; exit; end; (* stringa numero con segno, copia nella stringa nuova *) (* tutti i caratteri a partire dal secondo *) for i := 2 to lungh_s do begin c := s[i]; s_nuova := s_nuova + c; end; togli_segno_inizio := s_nuova; end; (* fine togli_segno_inizio *) (* riceve in input una stringa che rappresenta un numero, *) (* con o senza segno + - iniziale; rende in uscita una stringa *) (* con la stessa stringa-numero privata degli eventuali zeri *) (* iniziali; se non ci sono zeri iniziali, passa in uscita *) (* una stringa uguale a quella di input *) function togli_zeri_inizio(s: string): string; var s_nuova: string; lungh_s: longint; i_inizio: longint; i: longint; c: char; ok_togli_zero: boolean; begin s_nuova := ''; if ok_numero(s) = false then begin togli_zeri_inizio := s; exit; end; lungh_s := length(s); (* se la stringa-numero ha solo una cifra, *) (* non ci sono zeri da togliere *) if lungh_s = 1 then begin togli_zeri_inizio := s; exit; end; (* se la stringa-numero ha due carattereri e il primo *) (* e' un segno, non ci sono zeri da togliere *) if ((lungh_s = 2) and (ok_segno_inizio(s) = true)) then begin togli_zeri_inizio := s; exit; end; (* stringa senza segno iniziale formata solo da zeri *) if ((ok_segno_inizio(s) = false) and (ok_sottostr_char(s, '0', 1, lungh_s) = true)) then begin s_nuova := '0'; togli_zeri_inizio := s_nuova; exit end; (* stringa con segno iniziale formata solo da zeri *) if ((ok_segno_inizio(s) = true) and (ok_sottostr_char(s, '0', 2, lungh_s) = true)) then begin s_nuova := s[1] + '0'; togli_zeri_inizio := s_nuova; exit end; ok_togli_zero := true; (* i_inizio indica da dove iniziare la lettura dei caratteri di s *) if ok_segno_inizio(s) = true then begin i_inizio := 2; s_nuova := s[1]; end else begin i_inizio := 1; end; for i := i_inizio to lungh_s do begin c := s[i]; if c <> '0' then begin s_nuova := s_nuova + c; if ok_togli_zero = true then begin ok_togli_zero := false; end; end else begin if ok_togli_zero = false then begin s_nuova := s_nuova + c; end; end; end; togli_zeri_inizio := s_nuova; end; (* fine togli_zeri_inizio *) (* verifica se la stringa di input rappresenta un numero *) (* longint valido; in caso di esito positivo, assegna a p_num^ *) (* il valore corrispondente, altrimenti assegna 0 *) function ok_str_longint(s: string; p_num: p_longint): boolean; var str_minimo: string; str_massimo: string; str_limite: string; str_input: string; ok: boolean; lungh_s: longint; i: longint; begin p_num^ := 0; if ok_numero(s) = false then begin ok_str_longint := false; exit; end; (* stringhe-numero corrispondenti ai valori minimo/massimo *) (* assumibili da un longint *) str_minimo := IntToStr(low(longint)); str_massimo := IntToStr(high(longint)); (* se e' presente il segno meno, la verifica deve essere fatta *) (* con il valore minimo consentito *) if s[1] = '-' then begin str_limite := str_minimo; end (* altrimenti con il valore massimo *) else begin str_limite := str_massimo; end; (* la verifica viene fatta con stringa limite senza segno *) str_limite := togli_segno_inizio(str_limite); (* idem per la stringa-numero di input *) str_input := togli_segno_inizio(s); (* elimina dalla stringa di input eventuali zeri iniziali *) str_input := togli_zeri_inizio(str_input); (* la stringa-numero di input rientra nel range *) (* perche' ha meno cifre del limite *) if length(str_limite) > length(str_input) then begin p_num^ := StrToInt(s); ok_str_longint := true; exit; end; (* la stringa-numero di input non appartiene al range *) (* perche' ha piu' cifre del limite *) if length(str_limite) < length(str_input) then begin ok_str_longint := false; exit; end; ok := true; lungh_s := length(str_input); (* numero inserito e valore limite hanno lo stesso numero di cifre, *) (* legge in parallelo e confronta le cifre partendo dalla *) (* piu' significativa, procedendo da sinistra a destra *) for i := 1 to lungh_s do begin (* se la cifra del valore limite e' maggiore di quella *) (* del numero inserito, la capienza e' rispettata, *) (* quindi esce dal ciclo; ok rimane con valore true *) if ord(str_limite[i]) > ord(str_input[i]) then begin break; end; (* se la cifra del valore limite e' inferiore a quella *) (* del valore inserito, quest'ultimo e' fuori capienza *) if ord(str_limite[i]) < ord(str_input[i]) then begin ok := false; break; end; (* se le due cifre confrontate sono uguali, deve confrontare *) (* la coppia di cifre successiva *) end; if ok = true then begin p_num^ := StrToInt(str_input); end; ok_str_longint := ok; end; (* fine ok_str_longint *) (* riceve in input una stringa-numero che deve rappresentare *) (* un longint e passa in uscita il numero corrispondente; *) (* la stringa di input contiene la scritta che invita alla *) (* digitazione *) function leggi_longint(s: string): longint; var continua: boolean; stringa_num: string; ok: boolean; num: longint; begin continua := true; (* esce dal ciclo solo quando e' stato introdotta *) (* una stringa-numero valida *) while continua = true do begin write(s); readln(stringa_num); ok := ok_str_longint(stringa_num, @num); if ok = true then begin continua := false; end; end; leggi_longint := num; end; (* fine leggi_longint *) (* verifica se la stringa di input rappresenta un numero *) (* byte valido; in caso di esito positivo, assegna a p_num^ *) (* il valore corrispondente, altrimenti assegna 0; *) (* non ho previsto l'inserimento del segno *) function ok_str_byte(s: string; p_num: p_byte): boolean; var str_input: string; lungh_s: longint; str_massimo: string; ok: boolean; i: longint; begin p_num^ := 0; if ok_numero(s) = false then begin ok_str_byte := false; exit; end; if ok_segno_inizio(s) = true then begin ok_str_byte := false; exit; end; str_input := togli_zeri_inizio(s); lungh_s := length(str_input); if ((lungh_s < 1) or (lungh_s > 3)) then begin ok_str_byte := false; exit; end; if lungh_s < 3 then begin p_num^ := StrToInt(s); ok_str_byte := true; exit; end; (* valore massimo assumibile da un numero di tipo byte *) str_massimo := '255'; ok := true; (* numero inserito e valore massimo hanno entrambi 3 cifre; *) (* legge in parallelo e confronta le cifre partendo dalla *) (* piu' significativa, procedendo da sinistra a destra *) for i := 1 to 3 do begin (* se la cifra del valore massimo e' maggiore di quella *) (* del numero inserito, la capienza e' rispettata, *) (* quindi esce dal ciclo; ok rimane con valore true *) if ord(str_massimo[i]) > ord(str_input[i]) then begin break; end; (* se la cifra del valore massimo e' inferiore a quella *) (* del valore inserito, quest'ultimo e' fuori capienza *) if ord(str_massimo[i]) < ord(str_input[i]) then begin ok := false; break; end; (* se le due cifre confrontate sono uguali, deve confrontare *) (* la coppia di cifre successiva *) end; if ok = true then begin p_num^ := StrToInt(str_input); end; ok_str_byte := ok; end; (* fine ok_str_byte *) (* riceve in input una stringa-numero che deve rappresentare *) (* un numero byte e passa in uscita il numero corrispondente; *) (* la stringa di input contiene la scritta che invita alla *) (* digitazione *) function leggi_byte(s: string): byte; var continua: boolean; stringa_num: string; ok: boolean; num: byte; begin continua := true; (* esce dal ciclo solo quando e' stato introdotta *) (* una stringa-numero valida *) while continua = true do begin write(s); readln(stringa_num); ok := ok_str_byte(stringa_num, @num); if ok = true then begin continua := false; end; end; leggi_byte := num; end; (* fine leggi_byte *) (*--------------------------------*) end. (*--------------------------------*) (*--------------------------------*) (* fine lib_filtri.pas *)