Filtraggio caratteri nella finestra di input

di il
17 risposte

Filtraggio caratteri nella finestra di input

Ciao ragazzi. Sono nuovo del forum e ho cominciato da poco a scrivere alcuni semplici programmini

Ne ho completato uno sul calcolo dell'area del triangolo, e siccome devo mostrarlo ad un amico vorrei risolvere alcuni difetti che ho incontrato durante alcune prove. Il più difficile (per me ovvio ) da risolvere è il filtraggio di caratteri alfabetici (es. a, b..) nella finestra di input, in modo da lasciare all'utente la possibilità di inserire solamente numeri e punto (inteso come virgola nei decimali).

Questa è una parte di codice:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <cmath>
#include <windows.h>
#include <complex>


using namespace std;

int main()
{
    cout << "                               - calcolo dell'area del triangolo -" << endl;
    cout << string(2, '\n');
main:
    cout << "scegli la formula di calcolo:" << endl;
    cout << " a) formula base / altezza -- devi conoscere base e relativa altezza del triangolo" << endl;
    cout << " b) formula di Erone       -- devi conoscere i tre lati del triangolo" << endl;
    cout << " c) formula del seno       -- devi conoscere due lati e l'angolo tra essi compreso" << endl;
                cout << "" << endl;
                cout << "digita la lettera corrispondente alla formula" << endl;
                cout << "-- premi e per uscire" << endl;
                cout << "" << endl;
	int ch;
	do
	{
		ch = _getch();
	} while ( ( ch != 'a' ) && ( ch != 'e' ) && ( ch != 'b' ) && ( ch != 'c' ));
	if ( ch == 'a' )
	{
		goto one;
	}
	else if ( ch == 'b' )
	{
		goto two;
	}
	else if ( ch == 'c' )
	{
		goto three;
	}
	else
	{
		goto end;
	}
one:
    float altezza, base, area;
	int a;
	cout << "Base = ";
	cin >>(base);
	if (base <= 0)
	{
		cout << "anche una sola delle variabili non puo' risultare <= 0" << endl;
		goto one;
	}
	else
	{
	cout << "Altezza = ";
	cin >>(altezza);
	if (altezza <= 0)
	{
		cout << "anche una sola delle variabili non puo' risultare <= 0" << endl;
		goto one;
	}
	else
	{
	area = altezza * base / 2;
    cout.setf(ios_base::fixed, ios_base::floatfield);
    cout.precision(3);
	if (area < 0.0001)
	{
		cout << "hai inserito valori troppo bassi per il calcolo" << endl;
		goto one;
	}
	cout << "Area triangolo = ";
	cout << "bh/2 = ";
	a = printf("%.06g", area);
	cout << endl << "-- premi r per riprovare " << endl;
	cout << "-- premi b per passare alla formula di Erone " << endl;
	cout << "-- premi c per passare alla formula del seno " << endl;
	cout << "-- premi e per uscire " << endl;
	cout << "" << endl;
	do
	{
		ch = _getch();
	} while ( ( ch != 'r' ) && ( ch != 'b' ) && ( ch != 'e' ) && ( ch != 'c' ));
	if ( ch == 'r')
	{
		goto one;
	}
	else if ( ch == 'e')
	{
		goto end;
	}
	else if ( ch == 'c' )
	{
		goto three;
	}
	else 
	{
		goto two;
	}
	}
	}
Vorrei che ad esempio alla variabile "base" non fosse permesso l'inserimento di lettere, o che comunque apparisse un messaggio d'errore.
E' possibile? Grazie

17 Risposte

  • Re: Filtraggio caratteri nella finestra di input

    Mai usare goto in un programma se non in casi particolarissimi. Il tuo programma si risolve bennissimo con uno switch e dei do-while.
  • Re: Filtraggio caratteri nella finestra di input

    Scusa! in realtà ho fatto un po' di copia-delle funzioni che ho trovato in giro.. studierò bene una volta in vacanza
  • Re: Filtraggio caratteri nella finestra di input

    Nessuno che sappia come risolvere?

    skynet ha scritto:


    Il tuo programma si risolve bennissimo con uno switch e dei do-while.
    come e in che punto inserisco lo switch e i do-while?
  • Re: Filtraggio caratteri nella finestra di input

    Cosa sai dello switch?
  • Re: Filtraggio caratteri nella finestra di input

    skynet ha scritto:


    cosa sai dello switch?
    so che può essere utilizzato al posto di if-else e diventa un po' più ordinato, ma non so come inserirlo.. mi da un errore relativo alle variabili, perchè non sono costanti numeriche, ma probabilmente sono io che non so usarlo.
    comunque sia non noto questa differenza a livello di funzionalità: al posto di una rete di if-else hai switch-> case1, case2 ecc.

    Un'altra cosa: ho cambiato il tipo di variabile come "base" e "altezza" da float a long double.
  • Re: Filtraggio caratteri nella finestra di input

    Il resto lo fai tu.
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    	char ch = 0;
    
    	do 
    	{
    		cout << "                               - calcolo dell'area del triangolo -" << endl;
    		cout << string(2, '\n');
    		cout << "scegli la formula di calcolo:" << endl;
    		cout << " a) formula base / altezza -- devi conoscere base e relativa altezza del triangolo" << endl;
    		cout << " b) formula di Erone       -- devi conoscere i tre lati del triangolo" << endl;
    		cout << " c) formula del seno       -- devi conoscere due lati e l'angolo tra essi compreso" << endl;
    		cout << "" << endl;
    		cout << "digita la lettera corrispondente alla formula" << endl;
    		cout << "-- premi e per uscire" << endl;
    		cout << "" << endl;
    
    		cin >> ch;
    
    		switch(ch)
    		{
    			case 'a':
    			{
    				cin.ignore(100,'\n');
    				float altezza(0.0f), base(0.0f), area(0.0f);
    				bool valid = false;
    				do 
    				{
    					cout << "base: ";
    					cin >> base;
    					cout << "altezza: ";
    					cin >> altezza;
    					if(base > 0 && altezza > 0)
    						area = altezza * base / 2;
    					if(area > 0.0001)
    						valid = true;
    					if(!valid)
    					{
    						cout << "anche una sola delle variabili non puo' risultare <= 0" << endl;
    						cout << "oppure hai inserito valori troppo bassi per il calcolo" << endl;
    					}
    					cin.ignore(100,'\n');
    				} while (!valid);
    				cout << "Area triangolo = ";
    				cout << "bh/2 = ";
    				cout.setf(ios_base::fixed, ios_base::floatfield);
    				cout.precision(3);
    				cout << area << endl;
    			}
    			break;
    			case 'b':
    			{
    
    			}
    			break;
    			case 'c':
    			{
    
    			}
    			break;
    			default:
    			{
    				cout << "Errore selezione, riprova\n";
    				cout << string(10,'\n');
    			}
    		}
    	} while (ch != 'e');
    }
    
    come vedi nessun goto, nessuna inclusione di header che non servono e il programma funziona lo stesso.
  • Re: Filtraggio caratteri nella finestra di input

    Sto sostituendo i goto con lo switch..
    intanto ho anche provato questa combinazione per filtrare l'input:

    considero cin >> base
    
    char ibase;
    do
    {
        cout << "immissione non valida!";
        ibase = cin.width(base);
        cin.ignore(ibase, '\n');
        cin.clear(); 
    }
    while (cin.fail())
    
    ma mi ritorna un output di questo tipo:

    anche una sola delle variabili non può risultare <=0
    immissione non valida!

    anche una sola delle variabili non può risultare <=0
    immissione non valida!

    anche una sola delle variabili non può risultare <=0
    immissione non valida!
    ...

    e svariati errori riguardo alle conversioni double >> std::streamsize \\ std::streamsize >> char

    almeno c'ho provato
  • Re: Filtraggio caratteri nella finestra di input

    
    ...........
        cin.clear();
    }
    while (cin.fail())
    
    non vanno mai insieme. clear pulisce anche lo stato fail.
  • Re: Filtraggio caratteri nella finestra di input

    In teoria è quello che dovrebbe succedere:
    1) se fallisce mi dice: "immissione non valida!"
    2) cancella tanti caratteri quanti sono quelli dell'input + '\n'
    3) resetta con cin.clear() in modo da garantire una nuova immissione nella variabile

    comunque ho tolto cin.clear() per provare e questo è l'output:

    immissione non valida!
    immissione non valida!
    ...
  • Re: Filtraggio caratteri nella finestra di input

    Posta il codice completo così vai a tentativi.
  • Re: Filtraggio caratteri nella finestra di input

    Si ma sto avendo molti problemi a cambiare da goto a switch.. credo che lo farò in un secondo momento, devo capire bene come usarlo.

    Intanto provo a concentrarmi sul problema degli input non validi, una volta risolto ci riprovo.
  • Re: Filtraggio caratteri nella finestra di input

    Il codice che ti ho postato io non ti piaceva? Non aveva i goto e aveva lo swicth. Che devi fare altro?
  • Re: Filtraggio caratteri nella finestra di input

    Si ma con i continui rimandi con goto potevo tornare all'inizio ogni volta che l'utente sbagliava qualcosa.
    ad esempio con il tuo codice devo aspettare che tutte e due le variabili siano compilate prima di dirgli "no! stai sbagliando! hai inserito un valore negativo!".
    e poi non so perchè:
    1) l'approssimazione a 6 cifre significative non funziona, mi rimangono gli zeri non necessari dopo la virgola (considerando le variabili come double --> ("%.6f", variabile))
    2) ogni volta che effettuo la selezione per passare da una formula all'altra mi compare sullo schermo la lettera della tastiera che ho premuto (inoltre devo premere invio)

    posso sapere perchè goto non si usa in questo modo?
  • Re: Filtraggio caratteri nella finestra di input

    Perche la stessa cosa che fa il goto lo fa il while. il goto fa un salto incondizionato in una parte di programma dove tu non sai lo stato precedente dei variabili. E' da considerarsi abbastanza pericoloso specialmente se non si sa quel che si ta faccendo. Io te l'ho fatto x 3 variabili tu inglobba solo una variabile nel do-while. Lascia stare il goto, dimenticati della sua esistenza. produrrai codice migliore, fidati.
Devi accedere o registrarti per scrivere nel forum
17 risposte