La stringa Caratteri_Validi contiene tutti i caratteri alfabetici minuscoli, comprese le vocali accentate: 'qwertyuiopèéòàùìasdfghjklzxcvbnm'
La stringa Elemento contiene alcuni di quei caratteri alfabetici, oltre alla presenza di qualche carattere numerico: 'pa5ro8la'
Lo scopo è quello di esaminare, uno alla volta, i caratteri di Elemento e confrontarli con (uno alla volta) i caratteri della stringa Caratteri_Validi.
Se c'è una corrispondenza, "riempe" la Stringa_valida un carattere valla volta, altrimenmti esclude il carattere estraneo.
In parole povere, quindi, da ''pa5ro8la'' si dovrebbe arrivare a 'parola', che verrebbe finalmente aggiunta a ListBox1.
Però non appena il conteggio parte...
For Conta_Caratteri:= 1 to Length(Caratteri_Validi) do;
...immediatamente Conta_Caratteri, invece che a 1, viene inizializzato con 38 (la lunghezza di Caratteri_Validi).
La stessa cosa, ovviamente(!) succede con...
For Conteggio_Stringa:= 1 To Length(Elemento) do;
Perché i conteggi non partono da 1, come dovrebbero?
procedure TForm1.Button1Click(Sender: TObject);
Var Elemento, Caratteri_Validi, Stringa_valida, Carattere_selezionato: string;
Var Conta_Caratteri, Conteggio_Stringa: integer;
begin
Stringa_valida:='';
Conteggio_Stringa:=0;
Elemento:='pa5ro8la';
Caratteri_Validi:='qwertyuiopèéòàùìasdfghjklzxcvbnm'; // Intero alfabeto minuscolo, comprese vocali accentate
Begin
// DOVREBBE(!) leggere un carattere alla volta, partendo DAL PRIMO di "Caratteri_Validi"
// INVECE "Conta_Caratteri" invece di 1 inizia subito dalla lunghezza di "Caratteri_Validi" (38)
For Conta_Caratteri:= 1 to Length(Caratteri_Validi) do;
Begin
For Conteggio_Stringa:= 1 To Length(Elemento) do;
// La stessa cosa con "Conteggio_Stringa". Perché?
Begin
Carattere_selezionato:= Copy(Elemento,Conteggio_Stringa,1);
If Pos(Carattere_selezionato,Caratteri_Validi) > 0 Then
Begin
Stringa_valida:=Stringa_valida + Carattere_selezionato;
End;
End;
end;
End;
ListBox1.Items.Add(Stringa_valida);
Refresh;
End;
In questo modo rifai il loop di controllo del carattere da testare, partendo dal primo fino all'ultimo carattere ammesso, moltiplicato per tutti i caratteri stringa da controllare ... funziona ma... :-[
In alternativa a due loop, si può utilizzare per la parte controllo un Set con la keyword In
il Set è la sequenza di lettere corrette,
al posto della ShowMessage:
componi la stringa quando il valore è vero,
viceversa non fai nulla
Chiaramente il Set lo puoi/devi definire ad un livello superiore di chiamata, in modo da non doverlo inizializzare ogni volta
// Test if a character is a letter
procedure TForm1.IsLetter(Letter : char);
var
Alphabet : set of 'A'..'Z';
begin
Alphabet := ['A'..'Z'];
if Letter In Alphabet then
ShowMessage(Letter+' is in the alphabet')
else
ShowMessage(Letter+' is NOT in the alphabet');
end;
oppure così
var
Elemento, Caratteri_Validi, Stringa_valida: string;
i: integer;
begin
Stringa_valida := '';
Conteggio_Stringa := 0;
Elemento := 'pa5ro8la';
Caratteri_Validi := 'qwertyuiopèéòàùìasdfghjklzxcvbnm'; // Intero alfabeto minuscolo, comprese vocali accentate
for i := 1 to Length(Elemento) do
if Pos(Elemento[i], Caratteri_Validi) > 0 then
Stringa_valida := Stringa_Valida + Elemento[i]
ListBox1.Items.Add(Stringa_valida);
Refresh;
Fate attenzione che le stringhe che contengono caratteri UTF8 (quelli accentati per intenderci) devono essere confrontati con le funzioni equivalenti UTF8 (quindi non con POS())....
...uhmm... utilizzando POS() individuo tutte le vocali accentate (àèéìòù). Ho infatti appena completato un Video Tutorial che (spero) pubblicherò oggi pomeriggio.
Piuttosto, sarebbe certamente utile approfondire la gestione dei caratteri UTF8 per andare "oltre" il valore 127.
Esempio banalissimo (vedi anche screenshot) nel progetto qui di seguito indicato: il carattere ä viene individuato (ma davvero corrisponde a 195?) ma il viceversa produce un risultato... nullo.
P.S. La variabile s non c'entra nulla: è un rimasuglio di un test precedente. ;)
procedure TForm1.Button1Click(Sender: TObject);
Var Valore: Integer;
Var Carattere: string;
begin
If Length(Edit1.text)> 0 then
Begin
Carattere:= LeftStr(Edit1.Text,1);
Valore:= integer(Ord(Edit1.text[1]));
ShowMessage(Carattere);
Label2.Caption:= ('Il valore ASCII di ' + Carattere + ' è: ' + IntToStr(Valore));
end;
end;
procedure TForm1.Button2Click( Sender: TObject);
Var Numero: Byte;
Var Carattere, S: String;
Begin
Numero:= StrToInt(Edit2.Text);
Carattere:= Chr(Numero);
Label4.Caption:= ('Il carattere ASCII corrispondente è: ' + Carattere);
end;
[/]
Occhio, che stai facendo confusione !!!
Con UTF8, alcuni caratteri occupano 2 bytes. Dall'ultima immagine che hai postato, vedi che c'è qualcosa che non va, perché invece di emettere il carattere, emette il punto di domanda. Probabilmente, quel carattere è dato dal valore ascii 195, + quello successivo.
Provo a piegarmi con un esempio:
ShowMessage(IntToStr(Length('à')));
Il codice qui sopra, ti emetterà 2, e non 1 !!!
Ciao, Mario