* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Novembre 24, 2024, 08:57:55 am

Inserisci il nome utente, la password e la durata della sessione.

62 Visitatori, 0 Utenti

Autore Topic: Routine per avere numeri da stringhe  (Letto 13971 volte)

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Routine per avere numeri da stringhe
« il: Novembre 07, 2016, 10:17:00 pm »
Ci sono delle routine nella libreria che mi permettano da una InputBox (che restituisce una stringa) il controllo e trasformazione dell'input in valore Currency? ; mi spiego:
la routine dovrebbe controllare che non vi siano caratteri alfabetici, che inserire un punto
equivalga a virgola ed infine controllata la correttezza dei caratteri immessi mi dia come
output un numero Currency.
Grazie
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2389
  • Karma: +10/-0
Re:Routine per avere numeri da stringhe
« Risposta #1 il: Novembre 08, 2016, 01:02:36 am »
Il tipo currency è un numero a virgola mobile.
Hai provato ad usare la property mask?
Ci sono dei componenti con caratteristiche simili a quelle che cerchi.
Controlla nella paletta dei componenti 😊
Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #2 il: Novembre 08, 2016, 10:43:21 pm »
Ho provato ad usarlo anche leggendo quanto riportato qua http://www.lazaruspascal.it/index.php?topic=278.0,
ma per inserire valori in Euro, non mi sembra molto pratico,
almeno per quanto concerne le mie conoscenze.
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

bonmario

  • Hero Member
  • *****
  • Post: 1360
  • Karma: +11/-1
Re:Routine per avere numeri da stringhe
« Risposta #3 il: Novembre 09, 2016, 08:07:22 am »
Ciao,
spero di non aver capito male la domanda.
Supponiamo che l'utente scriva il valore in una TEdit, puoi usare l'evento "OnKeyUp" della TEdit, per controllare il carattere immesso e,
- se non è un numero o un punto o una virgola, scartarlo
- se è un punto, sostituirlo con una virgola.

Se non ricordo male, per far sì che l'evento "OnKeyUp" della TEdit sia visto, devi settare nel form la proprietà KeyPreview a True.

Ciao, Mario

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #4 il: Novembre 09, 2016, 11:08:30 am »
Ho risolto alla maniera "Pascal" puro: ho provato cosi' e mi pare che giri perfettamente,
alla conferma della InputBox richiamo questa function; se poi avere suggerimenti e
miglioramenti sono ben accetti.
Grazie

Codice: [Seleziona]
function CeckNumber(Numero:string;var NumeroCurr:Currency):Boolean;
const MaxCar=20;
var NumeroVirgole,i:integer;
    ArrCar:array[1..maxcar] of string;
    ArrBool:array[1..maxcar] of boolean;
    LunghezzaNumero:integer;

begin
CeckNumber:=true;NumeroVirgole:=0;NumeroCurr:=0;
LunghezzaNumero:=length(Numero);
for i:=1 to maxcar do ArrCar[i]:='';
for i:=1 to maxcar do ArrBool[i]:=true;
for i:=1 to LunghezzaNumero do ArrCar[i]:=copy(Numero,i,1);
for i:=1 to LunghezzaNumero do if ArrCar[i]='.' then ArrCar[i]:=',';
for i:=1 to LunghezzaNumero
    do begin
    if (ArrCar[i]<>'1')and(ArrCar[i]<>'2')and(ArrCar[i]<>'3')and(ArrCar[i]<>'4')
       and(ArrCar[i]<>'5')and(ArrCar[i]<>'6')and(ArrCar[i]<>'7')and(ArrCar[i]<>'8')
       and(ArrCar[i]<>'9')and(ArrCar[i]<>'0')and(ArrCar[i]<>',') then ArrBool[i]:=false;
    end;
if ArrCar[1]='-' then ArrBool[1]:=true;
// conto quante virgole sono inserite se superano 1 il valore immesso è errato
for i:=1 to LunghezzaNumero do if ArrCar[i]=',' then inc(NumeroVirgole);
if NumeroVirgole>1 then CeckNumber:=False
                 else for i:=1 to LunghezzaNumero do if ArrBool[i]=false then CeckNumber:=false;
Numero:='';
for i:=1 to LunghezzaNumero do Numero:=Numero+ArrCar[i];
if CeckNumber then NumeroCurr:=strtofloat(Numero);
if Not CeckNumber then begin
                       NumeroCurr:=0;
                       showmessage('Valore numerico errato');
                       end;
end;
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2921
  • Karma: +20/-4
Re:Routine per avere numeri da stringhe
« Risposta #5 il: Novembre 09, 2016, 06:44:16 pm »
ciao
non so se sono arrivato tardi, ma ho trovato questa funzione

http://rosettacode.org/wiki/Determine_if_a_string_is_numeric#Pascal
Imagination is more important than knowledge (A.Einstein)

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #6 il: Novembre 09, 2016, 10:30:17 pm »
Be intanto ti ringrazio per la segnalazione;
la funzione va quasi bene ma la virgola non viene accettata.
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2389
  • Karma: +10/-0
Re:Routine per avere numeri da stringhe
« Risposta #7 il: Novembre 09, 2016, 11:26:11 pm »
 :)
Puntatori ... questi sconosciuti ;)

Faccio un esempio.
Non so nemmeno se compila, ma serve per capire l'idea che ho in testa ;)

Codice: [Seleziona]
function parseItalianNumber(number: PChar): currency;

  function parseIntegerNumber(var number: PChar): integer;
  begin
    Result := 0;
    while number^ in ['0', '9'] do
    begin
      Result := Result * 10 + (Ord(number^) - Ord('0'));
      Inc(number);
      if (number = '.') then
        Inc(number);
    end;
  end;

var
  parteIntera: integer;
  parteDecimale: integer;
  posizioniDecimali: integer;
begin
  posizioniDecimali := 0;
  parteDecimale := 0;
  parteIntera := parseIntegerNumber(number);
  if (number^ = ',') then
  begin
    inc(number);
    posizioniDecimali := length(number);
    parteDecimale := parseIntegerNumber(number);
  end;
  Result := parteIntera + (Math.power(10, -posizioniDecimali) * parteDecimale);
end;
     

Separando la parte intera da quella decimale, si può eseguire un parsing più agevole.

Questa funzione fa la conversione di un numero "stringa" in un numero "numerico".
Contrinua fintanto trova cifre comprese tra 0 e 9.
Ad ogni posizione aumenta il valore restituito facendo il calcolo del valore della cifra trovata.
Se trova un '.' come separatore delle migliai, lo ignora.
Codice: [Seleziona]
function parseIntegerNumber(var number: PChar): integer;
  begin
    Result := 0;
    while number^ in ['0', '9'] do
    begin
      Result := Result * 10 + (Ord(number^) - Ord('0'));
      Inc(number);
      if (number = '.') then
        Inc(number);
    end;
  end;

Esempio di come usarla:
Prendo la parte intera della stringa fornita.
Controllo se sono arrivato alla ',' e poi passo a parsare la parte decimale.
Prima di partire mi calcolo il numero di cifre (mi servono come 10 alla - x).
Parso la parte decimale e combino le due parti numeriche.

Codice: [Seleziona]
var
  parteIntera: integer;
  parteDecimale: integer;
  posizioniDecimali: integer;
begin
  posizioniDecimali := 0;
  parteDecimale := 0;
  parteIntera := parseIntegerNumber(number);
  if (number^ = ',') then
  begin
    Inc(number);
    posizioniDecimali := length(number);
    parteDecimale := parseIntegerNumber(number);
  end;
  Result := parteIntera + (Math.power(10, -posizioniDecimali) * parteDecimale);
end;
Poi ci sarebbero da implementare tutti i controlli di validità del numero fornito.
Punti per le migliaia che non sono a 3 caratteri di distanza. Doppie virgole.
Caratteri che non sono numerici ;)
Ci si può sbizzarrire come si vuole nei controlli..
Se non ti va di fare l'elevazione a potenza puoi fare 2 funzioni per il parsing.
Quella che moltiplica (parte intera) e quella che divide (parte decimale).
Ma tutti quegli array mi hanno solo confuso e non mi è chiaro a cosa servono ;)

Spero vada bene come traccia.

Stilgar
       
Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2389
  • Karma: +10/-0
Re:Routine per avere numeri da stringhe
« Risposta #8 il: Novembre 09, 2016, 11:30:43 pm »
PS:
Per i numeri negativi si può migliorare in questo modo :

Codice: [Seleziona]
var segno : integer;
  parteIntera: integer;   
  parteDecimale: integer;   
  posizioniDecimali: integer;
begin
  segno := 1;
  posizioniDecimali := 0;   
  parteDecimale := 0;
  if (numero^='-') then
  begin
    segno := -1;
    inc(number);
  end;
  parteIntera := parseIntegerNumber(number);   
  if (number^ = ',') then   
  begin     
    Inc(number);     
    posizioniDecimali := length(number);     
    parteDecimale := parseIntegerNumber(number);   
  end;   
  Result := segno * parteIntera + (Math.power(10, -posizioniDecimali) * parteDecimale);
end;
Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #9 il: Novembre 10, 2016, 11:17:53 am »
Stasera la provo, volevo solo spiegarti il principio per cui ho utilizzato gli array:
prendo il numero in formato stringa ed ogni carattere lo immetto in un array
in parallelo ho un array di tipo boolean tutto settato a true;
Per prima cosa trasformo se presente il carattere '.' in ',' cosi posso immettere i dati
da qualsiasi tastiera (non come con google spreadsheet che non accetta come virgola
il punto);
inizio la scansione del primo carattere se è un numero ok altrimenti l'array parallelo va a false
in corrispondenza;
terminata la scansione se un solo elemento dell'array booleano è false allora  non è un numero.
Mi pare che funzioni bene e anche concettualmente corretta, vorrei però una vostra opinione
(ad esempio: la tua soluzione è una c.....a pazzesca  ;D)
Nicola
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2389
  • Karma: +10/-0
Re:Routine per avere numeri da stringhe
« Risposta #10 il: Novembre 10, 2016, 08:10:20 pm »
Ciao Nicola.
Nessuna soluzione è una caga... pazzesca.
Ci sono quelle più veloci e quelle meno veloci.
Se usi le eccezioni puoi dare un'informazione aggiuntiva all'utilizzatore della tua funzione.
Se "spacca" vuol dire che non ha passato un numero valido.
Se restituisce il valore vuol dire che è un numero valido.

Le eccezioni sono un canale "parallelo" di comunicazione. Se scattano vuol dire che ci sono errori.
Basta non abusarne ;)

 
Citazione
terminata la scansione se un solo elemento dell'array booleano è false allora  non è un numero.
Cmq. Al posto di un array per tenere lo stato, non sarebbe più efficente usare una singola variabile booleana?
Tanto basta che ci sia un valore degli n che salvi a farti capire che non è un numero.
Citazione
Mi pare che funzioni bene e anche concettualmente corretta
Se funziona bene non ci sono problemi.
Che sia concettaualmente corretta, non so cosa dirti. E' un'affermazione che non capisco :)
Sarà che da vecchio programmatore del "concettuale" non so come farlo stare dentro al processore :p

A parte gli scherzi.
Usare i puntatori potrebbe aprirti nuove strade.
Iniziare a fare il parsing con i puntatori per scoprire se è un numero o meno, potrebbe portarti a scrivere un parser sintattico. ;)
Gli array sono comodi, ma a volta mi stanno strettini ;) Preferisco di gran lunga i puntatori :)

Detto questo lascio la parola anche agli altri :)

Stilgar
Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #11 il: Novembre 10, 2016, 11:44:51 pm »
Gentilissimo Stilgar
non so se questo sia il luogo appropriato per rispondere in quanto andrei un po OT;
intanto ti ringrazio per avermi ricordato che esistono anche i puntatori e mi si è RI-aperto
un mondo che avevo abbandonato (per lavoro) nel 1986. Stavo cercando
di implementare un applicativo per la gestione dei cespiti della mia azienda (ovviamente come avrai capito dal tono delle mie domande a livello amatoriale per pura passione), e
nel farlo utilizzo spesso gli array che potrei tranquillamente sostituire con i puntatori,
(almeno cosi' ricordo). Ora per "digerire" la tua versione della funzione mi sa che dovrò
applicarmi piu' del previsto, soprattutto per capirla appieno. Vorrei ringraziare ancora
una volta tutti quanti gli utenti del forum che perdono tempo per le mie domande da
nubbio.
Nicola
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2389
  • Karma: +10/-0
Re:Routine per avere numeri da stringhe
« Risposta #12 il: Novembre 11, 2016, 12:37:50 am »
Ciao Nicola.
Alcuni colleghi avrebbero da ridire sul "gentilissimo" :)
Vedo che siamo veneti tutti e due ... diciamo che ho il "va in mona" facile :)
Per non dire che mi lascio andare a qualche intercalare tipico di Merghera ;) E non proprio lo "sbicio" o simili :) Quello originale insomma 

Per il resto, se hai bisogno chiedi pure.
Il forum serve per questo :)

Stilgar
Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

MadPascal

  • Newbie
  • *
  • Post: 3
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #13 il: Novembre 11, 2016, 06:37:45 pm »
Spero di poter essere ancora di aiuto, mostrando due metodi che io uso, uno consiste nel verificare la sintassi di un numero in virgola mobile ed un metodo che intercetta le eccezioni.

Metodo 1

Codice: [Seleziona]
function CheckNumber(Numero:ansistring;var NumeroCurr:Currency):Boolean;
var i,punti:byte;
    valido:boolean;
begin
  valido:=true;
  punti:=0;
  for i:=1 to length(numero) do
      begin
        if numero[i]='.' then numero[i]:=',';
        if numero[i] in ['0'..'9',',']
           then begin
                  if numero[i]=',' then inc(punti);
                end
           else valido:=false;
      end;
  if punti>1 then valido:=false;
  if length(numero)=0 then valido:=false;
  if (numero[1]=',') or (numero[length(numero)]=',') then valido:=false;
  if valido then numerocurr:=StrToFloat(numero);
  result:=valido;
end;

Questo metodo converte gli eventuali punti in virgole e verifica che la stringa contenga solo numeri e virgole. Inoltre conta anche le virgole, perchè qualcuno potrebbe inserire più punti o virgole.
Se la sintassi del numero è corretta, procede alla conversione da stringa a valore numerico.


Metodo 2

Codice: [Seleziona]
function CheckNumberEx(Numero:ansistring;var NumeroCurr:Currency):Boolean;
var valido:boolean;
begin
  valido:=true;
  Numero:=AnsiReplaceText(numero,'.',',');
  try
    Numerocurr:=StrToFloat(Numero);
  except
    valido:=false
  end;{try}
  result:=valido;
end;

Questo metodo richiede che nell'elenco delle unità nella sezione USES sia inserita anche STRUTILS
Dal codice si capisce che la prima riga sostituisce i punti con le virgole, successivamente esegue la conversione da stringa a valore numerico. Se si verifica un errore, il programma non lo mostra, ma esegue semplicemente quello che c'è tra except e end;{try}
Quando si esegue un programma con try nell'IDE del lazarus, l'IDE comunque mostra una notifica dell'eccezione, ma se il programma viene eseguito con il doppio click dell'exe, la finestra dell'eccezione non verrà mostrata.

Nicola

  • Full Member
  • ***
  • Post: 201
  • Karma: +0/-0
Re:Routine per avere numeri da stringhe
« Risposta #14 il: Novembre 11, 2016, 10:00:00 pm »
Vi dico solo che per "colpa" vostra sto ripassando puntatori, liste dinamiche  e pile   :'( :'( :'(
Gli esempi sono entrambi efficaci con spunti utili per approfondire il problema da punti di vista diversi.
Ora vado un po' OT, ho scaricato alcuni PDF per un ripasso dei puntatori fra cui una dispensa del Prof. LUCIO VARAGNOLO mio prof. di informatica al Sarpi di Venezia
nel periodo 83-85, quasi mi metto a piangere....
« Ultima modifica: Novembre 11, 2016, 10:45:13 pm da Nicola »
La disumanità del computer sta nel fatto che una volta
programmato e messo in funzione, si comporta in
maniera perfettamente onesta.

 

Recenti

How To

Utenti
  • Utenti in totale: 803
  • Latest: maXim.FI
Stats
  • Post in totale: 19180
  • Topic in totale: 2288
  • Online Today: 97
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 62
Total: 62

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.