Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: AlexLazarus - Ottobre 19, 2022, 08:21:17 am

Titolo: Gestione stringhe in una TEdit [RISOLTO]
Inserito da: AlexLazarus - Ottobre 19, 2022, 08:21:17 am
Da circa cinque anni avevo abbandonato la programmazione (Visual Basic) e ho voluto riprendere installando Lazarus per la prima volta.
Ero abituato a gestire i Text Box con enorme disinvoltura, ma in Lazarus incontro enormi difficoltà.
Il programma dello screenshot è più che altro un programmino semplice-semplice di test, solo per prendere confidenza con il nuovo strumento di sviluppo.
Come si può vedere nello screenshot, non riesco a "estrarre" la stringa presente per esaminare - carattere dopo carattere - il suo contenuto.
Se, invece, inserisco dati numerici, il programma funziona perfettamente.
Dove sbaglio?
Grazie in anticipo a chi vorrà darmi qualche dritta.
Titolo: Re:Gestione stringhe in una TEdit
Inserito da: giacomarko - Ottobre 19, 2022, 09:39:55 am
da quello che ho capito dallo screenshot,

ma se il valore di InpRaggio è "pippo" e poi tenti di moltiplicarlo, è ovvio che ottieni un errore,

anche la sequenza delle istruzioni dovrebbe essere rivista, a rigore di logica prima dovresti:

a.  testare il valore di input per capire che quanto digitato sia un numero, caratteri ammessi da "0" a "9" e "." o ","

b. solo se il controllo è positivo, allora convertire la stringa in numero, altrimenti messaggio utente : hai sbagliato a digitare

c. effettuare le operazioni che ti servono

m
Titolo: Re:Gestione stringhe in una TEdit
Inserito da: AlexLazarus - Ottobre 19, 2022, 09:57:54 am
Evidentemente non mi sono spiegato bene.
1) Come si può notare, (ShowMessage eccetera) la stringa NON viene proprio accettata PRIMA di essere essere sottoposta a elaborazione.
2) Digitando valori numerici il programma gira perfettamente (notare i due risultati)
Titolo: Re:Gestione stringhe in una TEdit
Inserito da: AlexLazarus - Ottobre 19, 2022, 10:01:25 am
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Label1: TLabel;
    ListBox1: TListBox;
    PulCalcola: TButton;
    InpRaggio: TEdit;
    OutDato: TLabel;
    procedure ListBox1Click(Sender: TObject);
    procedure PulCalcolaClick(Sender: TObject);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.PulCalcolaClick(Sender: TObject);
Var Raggio, Diametro, Circonferenza, Area: Real;
   MyString: String;

begin
  Raggio:= StrToFloat(InpRaggio.Text);
  MyString:=InpRaggio.Text;
  ShowMessage(MyString);
  (*  ShowMessage(InpRaggio.Text);
      InpRaggio.text:='78';
      // Controllo dato *)
  If InpRaggio.Text = 'pippo' Then
     begin
       ShowMessage('Hai digitato pippo');
     end;
  // Qui NON ci vuole ELSE
  Diametro:= Raggio*2;
  Circonferenza:= 2 * Raggio* 3.1415;
  Area:= Raggio * Raggio * 3.1415;
  OutDato.Caption:='Diametro: '+ FloatToStr(Diametro);

  ListBox1.Items.Add('Raggio' + ': ' +  FloatToStr(Raggio));
  ListBox1.Items.Add('Diametro' + ': ' +  FloatToStr(Diametro));
  ListBox1.Items.Add('Circonferenza' + ': ' +  FloatToStr(Circonferenza));
  ListBox1.Items.Add('Area' + ': ' +  FloatToStr(Area));
  ListBox1.Items.Add('-----------------');
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin

end;

end.
     
Titolo: Re:Gestione stringhe in una TEdit
Inserito da: giacomarko - Ottobre 19, 2022, 11:49:01 am
Hai provato con il debug passo-passo per vedere dove si genera l'errore ?

secondo me il problema è la sequenza delle istruzioni, secondo quanto scrivi, per prima cosa cerchi di trasformare "pippo" in un float, cosa che ovviamente genere un errore runtime, mentre invece se l'input è realmente un valore numerico il programma fuziona, come tu stesso dici

begin
  Raggio:= StrToFloat(InpRaggio.Text);  // qui si generà l'errore -> raises an exception if s is not the textual representation of a float

  MyString:=InpRaggio.Text;                 // questa non viene eseguita a causa dell'errore precedente
....
end;

Come ti suggerivo nel post precedente, dovresti testare prima che tutti gli input siano effettivamente dei valori numerici, e successivamente iniziare con i calcoli

begin
  MyString:=InpRaggio.Text;

    // implementa qui un controllo su MyString e solo se è realmente un numero procedi
  testNumero:=(Verifico se MyString rappresenta correttamente un numero);

  if Not testNumero then ShowMessage( 'Il valore digitato '+MyString+' non è un valore numerico')
  else
  begin
     Raggio:= StrToFloat(MyString);
     Diametro:= Raggio*2;
       ....
  end;
...
end;

altra cosa sull'uso dei blocchi, leggendo questo pezzo di codice

  If InpRaggio.Text = 'pippo' Then
     begin
       ShowMessage('Hai digitato pippo');
     end;
  // Qui NON ci vuole ELSE
  Diametro:= Raggio*2;
  Circonferenza:= 2 * Raggio* 3.1415;
  Area:= Raggio * Raggio * 3.1415;
  OutDato.Caption:='Diametro: '+ FloatToStr(Diametro);

in pratica fai un test di congruenza su un dato, e se non è ok avvisi l'utente... perfetto.

ma se non metti else e racchiudi in un blocco il codice che segue, questo verrà eseguito comunque, anche se InpRaggio.Text non è un numero

Titolo: Re:Gestione stringhe in una TEdit
Inserito da: AlexLazarus - Ottobre 19, 2022, 04:07:13 pm
Aargh! Hai perfettamente ragione. 😥

Mi sono quindi subito messo all'opera per risolvere, ma... (ripeto, ho iniziato da pochissimo) non vedo le istruzioni / comandi che gestivo comodamente in Visual Basic.
Ho trovato l'elenco delle parole chiave di Lazarus (https://wiki.freepascal.org/Reserved_words) ma noto l'assenza delle istruzioni relative alla gestione delle stringhe. Per esempio:

Len(Stringa) // Per determinare la lunghezza di una stringa
Instr$ // Per individuare l'ennesimo carattere presente all'interno di una stringa

...e così via. Dubito che in Lazarus manchino queste istruzioni e mi chiedo dove possa trovarle.

Grazie per la pazienza. ❤
Titolo: Re:Gestione stringhe in una TEdit
Inserito da: giacomarko - Ottobre 19, 2022, 04:39:01 pm
Be ci vuole pazienza, un aiuto sicuramente lo puoi trovare qui: http://www.lazaruspascal.it/index.php (http://www.lazaruspascal.it/index.php)
ti suggerisco nel contempo, di investire un po di tempo nell'apprendimento delle strutture del Pascal, che differiscono dal Basic, poi i comandi poco a poco li impari...

per rispondere immediatamente alla tua domanda:

BASIC->              Len(Stringa) // Per determinare la lunghezza di una stringa
Pascal/Lazarus -> Length(Stringa) restituisce il numero di caratteri di Stringa

BASIC->              Instr$ // Per individuare l'ennesimo carattere presente all'interno di una stringa
Pascal/Lazarus -> Pos( cosa, dove)... Pos('a', Stringa) restituisce la prima posizione trovata di 'a' in Stringa


ad ogni modo un approccio "semplice" al tuo problema potrebbe essere il seguente:

procedure TForm1.BitBtnCalcolaClick(Sender: TObject);
var
  f: real;
begin
  // funzione integrata che tenta la conversione e restituisce un valore true se ok e il valore numerico già convertito in f
  if TryStrToFloat( Edit1.Text, f) then       
  begin
   // era true quindi esegui i calcoli ...
    ...
    ...
    ShowMessage(' Risultato = '+ FloatToStr( f * 1.5) );
  end   
  else // era false quindi errore di conversione !
  begin
    ShowMessage( 'Non hai digitato un numero, ma : ' + Edit1.Text); // avviso l'utente
    Edit1.Text:='';   // azzero il controllo input
  end;
end;
Titolo: Re:Gestione stringhe in una TEdit [RISOLTO]
Inserito da: AlexLazarus - Ottobre 19, 2022, 05:33:20 pm
giacomarko: grazie mille, gentilissimo! ❤

P.S. Metterei un Like, ma vedo che non è possibile mettere emoticons.