Newsgroup: it.comp.programmare.win32
Titolo: Impedire inserimento di piu di una virgola

Salve,
in C++ Builder 3 vorrei impedire che l'utente immetta piů di una virgola in 
una Text Edit.
Il seguente codice:
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
    String s = Edit1->Text;
    bool virgola = false;
    for (int i = 1; i <= s.Length(); i++)
        if ((s[i] == ',') && (!virgola))
            virgola = true;
        else
        if ((s[i] == ',') && (virgola))
            s.Delete(i, 1);
    Edit1->Text = s;
}
fa quello che voglio perň non appena digito la seconda virgola il cursore si 
sposta all'inizio della stringa e se continuo a premere virgola 
ripetutamente cancella quella gia inserita.
Come posso fare in modo che il cursore all'interno della text edit rimanga 
sempre alla fine della stringa?
Grazie

 una virgola in una Text Edit.
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char 
&Key)
{
    if ((Key == ',') && (Edit1->Text.Pos(",") != 0)) Key = 0;
}
HTH,
-- 
Stefano Frosio
www.esse-effe.com

 }
Grazie, ma mi potresti spiegare il codice da te scritto per usi successivi?
Da quanto leggo ho capito che la condizione if valuta se il carattere 
immesso e' una virgola e se ci sono altre virgole gia inserite ricavandone 
la posizione.
Ma quel Key = 0 cosa vuol dire? Indica proprio l'impedimento 
dell'inserimento del carattere ","?
Grazie 

Il seguente codice non dovrebbe consentire di convertire i punti in virgola 
e di accettare solo valori numerici e una sola occorrenza di virgole?
void __fastcall TMainPrezzo::indiceKeyPress(TObject *Sender, char &Key)
{
    if (Key == '.')
        Key = ',';
    if ((Key == ',') && (indice->Text.Pos(",") != 0) ||
         (Key != '0') || (Key != '1') || (Key != '2') ||
         (Key != '3') || (Key != '4') || (Key != '5') ||
         (Key != '6') || (Key != '7') || (Key != '8') ||
         (Key != '9'))
        Key = 0;
}
Grazie 

        Key = 0;
Ho sbagliato operatore logico, ci vuole and ovviamente :-) 

Ho notato che lo stesso codice a volte funziona a volte no, senza motivo.
Ad esempio:
 if (Key == '.')
        Key = ',';
    if ((Key == ',') && (indice->Text.Pos(",") != 0) ||
         (Key != '0') && (Key != '1') && (Key != '2') &&
         (Key != '3') && (Key != '4') && (Key != '5') &&
         (Key != '6') && (Key != '7') && (Key != '8') &&
         (Key != '9') && (Key != '\b'))
        Key = 0;
All'improvviso non leggeva più nessuna virgola ne punto.
A questo punto non so come fare per fargli leggere solo la virgola una 
volta, le 10 cifre decimali, il backspace (\b funziona) e convertire i punti 
in virgole. Il precedente codice funzionava, all'improvviso non sta 
funzionando più.
Ciao 

Ecco il quinto post di fila... penso di aver risolto con una modifica, ma è 
strano quanto successo prima, sarà stata la fretta... 

 dell'inserimento del carattere ","?
In pratica il tasto premuto non viene ulteriormente elaborato 
dal TEdit, che quindi non lo aggiunge.
-- 
Stefano Frosio
www.esse-effe.com

 modifica
Meglio così. Comunque se a quanto ho capito il tuo scopo è 
quello di limitare l'inserimento del separatore decimale, ti 
consiglio l'utilizzo della variabile DecimalSeparator anzichè 
forzare l'uso del punto o della virgola, in modo da adeguarsi 
alle impostazioni del sistema.
-- 
Stefano Frosio
www.esse-effe.com

 virgola, in modo da adeguarsi alle impostazioni del sistema.
Si, in pratica in quelle text edit devo inserire valori in euro.
Come si usa DecimalSeparator?
Grazie 

 Come si usa DecimalSeparator?
Dalla guida:
extern PACKAGE char DecimalSeparator;
DecimalSeparator is the character used to separate the integer 
part from the fractional part of a number. The initial value is 
fetched from LOCALE_SDECIMAL.
Quindi, per esempio:
void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char 
&Key)
{
    if ((Key == DecimalSeparator) && 
(Edit1->Text.Pos(DecimalSeparator) != 0)) Key = 0;
}
-- 
Stefano Frosio
www.esse-effe.com

 }
Ah ok grazie.
Ma non capisco perché i double usino come separatore la virgola e non il 
punto, come avviene in C++ standard.
E' possibile settare questa impostazione del linguaggio? 

 virgola e non il punto, come avviene in C++ standard.
I double non usano come separatore la virgola. La frase in 
realtà non ha alcun senso poichè la virgola può essere 
utilizzata nella rappresentazione di un double, o di un numero 
decimale, il quale però non ha il concetto di separatore 
decimale. E comunque per assegnare un double, ad esempio, in 
C++, come in altri linguaggi, il separatore è il punto, non la 
virgola:
double x = 1.2;
-- 
Stefano Frosio
www.esse-effe.com

 double x = 1.2;
Si ma la seguente stringa da errore:
double d = StrToFloat("3.8");
mentre questa no:
double d = StrToFloat("3,8");
Ciao 

 double d = StrToFloat("3,8");
Dalla guida, su StrToFloat:
The DecimalSeparator global variable defines the character that 
must be used as a decimal point.
Evidentemente nel tuo sistema hai impostato la virgola come 
separatore decimale, quindi "3.8" non può essere convertito, 
mentre "3,8" sì.
-- 
Stefano Frosio
www.esse-effe.com

 decimale, quindi "3.8" non può essere convertito, mentre "3,8" sì.
Si ma secondo me la notazione col punto dovrebbe essere sempre supportata 
visto che i double la usano a livello di linguaggio.
Ciao 

 linguaggio.
Un conto è inserire un numero decimale a livello di codice, un 
conto è convertire una stringa. Nel tuo caso stai convertendo 
una stringa ed il fatto che StrToFloat agisca in base al 
separatore decimale di sistema è un vantaggio (StrToFloat non è 
standard, ma inclusa nelle VCL). Se invece stai cercando 
qualcosa di standard devi utilizzare atof, in quel caso però il 
separatore decimale deve essere un punto.
-- 
Stefano Frosio
www.esse-effe.com

 }
Che pasticcio :-)
Ma in C non esiste qualcosa di simile a if key in ('0'..'9') ??
Comunque io al tuo posto lascerei piena libertà all'utente di inserire 
quello che vuole, e solo *dopo* farei il controllo
// delphi:
try
	value := Strtofloat(Edit1.Text);
	...
except
	ShowMessageFmt('%s is not a currency value', [Edit1.Text]);
end;

 convertire una stringa.
Si ma siccome viene convertito in un double secondo me sarebbe piů utile se 
sia la virgola che il punto fossero accettati e venissero automaticamente 
trasformati in punto.
Ciao 

 quello che vuole, e solo *dopo* farei il controllo
No, perché il calcolo avviene automaticamente man mano che inserisce, senza 
cliccare su un pulsante (ho messo il calcolo nell'evento onchange della text 
edit)
Ciao 

 venissero automaticamente trasformati in punto.
Il "problema" è che non puoi sapere a priori quale separatore 
decimale verrà impostato dall'utente (potrebbe persino non 
essere nè un punto nè una virgola, vedi qui: 
http://en.wikipedia.org/wiki/Decimal_separator
). Ed è per questo 
che consigliavo e consiglio l'utilizzo di DecimalSeparator.
E comunque per convertire i caratteri virgola in punto basta una 
StringReplace. Ma così facendo forzeresti la modalità di 
inserimento.
-- 
Stefano Frosio
www.esse-effe.com