Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: AlexLazarus - Novembre 09, 2022, 06:23:34 pm

Titolo: [RISOLTO] Gestione vocali accentate
Inserito da: AlexLazarus - Novembre 09, 2022, 06:23:34 pm
Sto entrando leggermente in confusione (come al solito).
Dunque...
Riesco a leggere correttamente una vocale accentata, ma non a gestirla.
Nell'esempio che allego il programma non ha problemi nel leggere il carattere Car (cui è associata la vocale accentata) né nel "concatenarla" con altri caratteri. Tuttavia (a quanto pare) a ogni vocale accentata vengono associati TRE caratteri, probabilmente si tratta del codice esadecimale (vedi secondo screenshot).
Il fatto è che dopo aver estratto da una stringa una vocale accentata, vorrei un "qualcosa" che mi dica: "La vocale accentata è: à" in modo che possa sottoporla a elaborazione successiva (Tipo: IF Car := 'è' THEN ... eccetera).

P.S. Ho già letto https://forum.lazarus.freepascal.org/index.php/topic,31387.0.html ma purtroppo non è molto chiaro.

Come fare?
Codice: [Seleziona]
{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
Var I:Integer;
  Car, Parola: String;
begin

     Parola:= '';
     For I := 1 to Length(Edit1.Text) do
       Begin
         Car:= Copy(Edit1.Text,I,1);
         ShowMessage(Car);
         Parola:= Parola + Car;
       End;
     Label1.Caption:='Parola: ' + Parola + ' Lunghezza: ' + IntToStr(Length(Parola));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label2.Caption:=('Lunghezza stringa: ' + IntToStr(Length(Edit1.text)));
end;

end.
Titolo: Re:Gestione vocali accentate
Inserito da: DragoRosso - Novembre 09, 2022, 07:07:49 pm
Ciao, volevo già porre l'attenzione su questo fatto in uno dei tuoi precedenti post, ma sembrava un pò off topic.

Attualmente, tenuto conto delle lingue che esistono al mondo non si possono più gestire i caratteri al vecchio modo (ANSI, CP, .....).

Tutti i caratteri diversi da quelli inglesi standard (codice ASCII da 32 a 127) vengono trattati come codifica UNICODE, ad esempio UTF8, UTF16.

Il carattere quindi non è più di un BYTE (in realtà il carattere, vedi il C++, non è più da tempo di un BYTE ma è formato da almeno due BYTE) ma bensi può arrivare ad essere anche di 4 byte.

Non puoi trattare caratteri con CHR o ORD in generale.

Adesso non ho tempo ma cerca LAZARUS e UTF8 e dovresti vedere un pò di luce.

Ciao

Titolo: Re:Gestione vocali accentate
Inserito da: giacomarko - Novembre 09, 2022, 07:16:45 pm
fai poi attenzione agli operatori

...in modo che possa sottoporla a elaborazione successiva...
Codice: [Seleziona]
(Tipo: IF Car := 'è' THEN ... eccetera).

non puoi usare
Codice: [Seleziona]
if
con
Codice: [Seleziona]
:=
Titolo: Re:Gestione vocali accentate
Inserito da: DragoRosso - Novembre 09, 2022, 10:31:31 pm
Eccomi. Qui un esempio su come iterare su una stringa con caratteri utf8.
Codice: [Seleziona]
//Inserire nella Uses:
Uses LazUtf8;

procedure TForm1.Button1Click(Sender: TObject);
var tempstr: string;
    car: string;
    UTtempstr: UnicodeString;
    UTcar: Unicodestring;
    i: integer;
begin
  tempstr := '这些是汉字';
  UTtempstr := tempstr;
  ShowMessage(tempstr);
  for i := 0 to UTF8Length(tempstr)-1 do
    begin
      car := Utf8Copy(tempstr, i+1, 1);
      ShowMessage(car);
      //Questo è solo un esempio.
      //Si possono usare le funzioni Utf8 per fare la ricerca (PosEx) o altro
      if car = '是' then
        ShowMessage('Carattere trovato');
    end;
  ShowMessage('Modo alternativo');
  //Ulteriore metodo con le stringhe Unicode
  for UTcar in UTtempstr do
    ShowMessage(UTcar)
end;

PS: inserito metodo alternativo.
Titolo: Re:Gestione vocali accentate
Inserito da: Mimmo - Novembre 10, 2022, 09:31:29 am
Ciao,
il tipo string di default in Lazarus è codificato con UTF-8 e qui trovi qualche delucidazione: https://wiki.lazarus.freepascal.org/String (https://wiki.lazarus.freepascal.org/String)
Tu ricordati che Length considera la stringa come un array di byte/caratteri, da qui il disallineamento logico che ti si è presentato. La stringa "àèìòù" ad esempio a livello di byte è lunga 10. Copy si comporta in modo allineato a Length, per cui il tuo ciclo di copia funziona come risultato finale (il for frullerebbe 10 volte nell'esempio). Anche Pos ragiona sempre come array di byte.
Quindi fintanto che li usi combinati per copiare o spezzettare stringhe, normalmente fila tutto liscio.
Se hai bisogno di manipolare la stringa ragionando per carattere, devi invece utilizzare le chiamate che ti ha fatto vedere DragoRosso.
Altre info le trovi qui: https://wiki.freepascal.org/Unicode_Support_in_Lazarus (https://wiki.freepascal.org/Unicode_Support_in_Lazarus) e qui: https://wiki.lazarus.freepascal.org/UTF8_strings_and_characters (https://wiki.lazarus.freepascal.org/UTF8_strings_and_characters)
Titolo: Re:Gestione vocali accentate
Inserito da: AlexLazarus - Novembre 10, 2022, 10:18:05 am
non puoi usare
Codice: [Seleziona]
if
con
Codice: [Seleziona]
:=
Sì, va be', era solo per indicare uno "schema" di applicazione. Ovvio che ci suole solo (=) e non (:=)-
Titolo: Re:Gestione vocali accentate
Inserito da: AlexLazarus - Novembre 10, 2022, 10:25:54 am
Eccomi. Qui un esempio su come iterare su una stringa con caratteri utf8.
...eccetera


GRANDISSIMO! (Non è che mi poi mandi la fattura per le consulenze, eh?) 🤔

Inserisco qui di seguito il mio modesto contributo (intero listato) e lo screenshot.
A proposito dei messaggi di errore, in molti programmi me ne compaiono spesso ma sembra che nonostante i vari "Warning" e le "Note" tutto funzioni sempre, senza problemi. Mah, non capisco, ma mi adeguo. (cit.)
Grazie ancora!
Codice: [Seleziona]
unit a_2022_11_09_Lazarus_vocali_pas;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, LazUtf8;
// LazUtf8 inserita nella uses per gestire vocali accentate

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
Var I:Integer;
  Car, Parola: String;
begin
     Parola:= '';
     For I := 1 to Length(Edit1.Text) do
       Begin
         Car:= Copy(Edit1.Text,I,1);
         ShowMessage(Car);
         Parola:= Parola + Car;
       End;
     Label1.Caption:='Parola: ' + Parola + ' Lunghezza: ' + IntToStr(Length(Parola));
end;

procedure TForm1.Button2Click(Sender: TObject);
// Gestione vocali accentate
// LazUtf8 inserita nella uses per gestire vocali accentate
var tempstr: string;
    car: string;
    UTtempstr: UnicodeString;
    // UTcar: Unicodestring;
    i: integer;
begin
     tempstr := edit1.Text;
     UTtempstr := tempstr;
  ShowMessage(tempstr);
  for i := 0 to UTF8Length(tempstr)-1 do
    begin
      car := Utf8Copy(tempstr, i+1, 1);
            //Si possono usare le funzioni Utf8 per fare la ricerca (PosEx) o altro
      if (car = 'à') OR (car = 'è') OR (car = 'é') OR (car = 'ì') OR (car = 'ò') Or (car = 'ù') then
            // ShowMessage('Carattere trovato');
        ListBox1.items.add('Pippo'+car);
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label2.Caption:=('Lunghezza stringa: ' + IntToStr(Length(Edit1.text)));
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
 Label3.Caption:=('Stringa selezionata: ' + ListBox1.items.strings[ListBox1.itemindex]);
end;

end.
Titolo: Re:Gestione vocali accentate
Inserito da: DragoRosso - Novembre 10, 2022, 02:14:43 pm
A proposito dei messaggi di errore, in molti programmi me ne compaiono spesso ma sembra che nonostante i vari "Warning" e le "Note" tutto funzioni sempre, senza problemi. Mah, non capisco, ma mi adeguo. (cit.)

I warning e le note (o hint in altri ambienti) sono messaggi di avvertimento che ti allertano su qualcosa di "sospetto" oppure ti consigliano qualche azione: tipici esempi sono le conversioni automatiche oppure l'indicazione di una variabile dichiarata ma non usata.

Normalmente ce ne sono a decine e una occhiata magari và data, ma nella stragrande maggioranza dei programmi si può tranquillamente ignorare.

P.S.: ho visto dopo il tuo screenshot, e guarda caso calza a pennello con quello che ti ho scritto.

Ciao