PDA

View Full Version : Calcolatrice


zergling
11-05-2007, 21:24
Ciao a tutti,
Inanzitutto vorrei precisare che sono un nubbio e che sono ancora alle prime armi :).
Detto cio, passiamo al codice sorgente:

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int num1, num2, add, sub, div, mol;
cout << "Please give me two integers numbers\n";
cout << "for example 2+5 or 78-4 etc.\n\n";
cin >> num1 >> num2;

if ( '+' )
{
add = num1 + num2;
cout << "= " << add << endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

if ( '-' )
{
sub = num1 - num2;
cout << "= " << sub << endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

if ( '/' )
{
div = num1 / num2;
cout << "= " << div << endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

if ( '*' )
{
mol = num1 * num2;
cout << "= " << mol << endl;
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}



system("PAUSE");
return EXIT_SUCCESS;
}

Funziona tutto correttamente a parte la divisione e la moltiplicazione :(

Dove ho sbagliato?
Ciao e grazie

MEMon
11-05-2007, 21:42
Sicuro che funzionare tutto correttamente? Io ne dubito guardando il codice.

Non può funzionare, sbagli già quando fai if('+'), che sarà sicurmemte sempre vera essendo '+' un valore diverso da zero e non nullo.
In più come fai ad essere sicuro che num1 e num2 sono numeri? hai controllato che non prenda anche gli operatori?

zergling
11-05-2007, 22:02
Si, se provi a compilare il file, vedrai che "+ e - " funzionano correttamente.

MEMon
11-05-2007, 23:18
... funzionano per puro caso.

-fidel-
12-05-2007, 08:24
Rivediti bene come funziona la condizione "if".
Inoltre ci devi spiegare dove leggi l'operatore.

@memon

c++ converte automaticamente il tipo di dato con l'operatore di estrazione >> in base al tipo a destra (non è come il C, essendo più type strict di C ti lascia meno libertà - e fa lui...), ovviamente quando ci riesce.
Infatti, con un minimo di eleganza, io farei così:


int operands[2];

...

for (unsigned char i = 0; i < 2; i++)
{
if ((cin >> operands[i] >> dec).fail())
{
cerr << "Operando " << (i + 1) << " non valido." << endl;
exit(1);
}
}

MEMon
12-05-2007, 10:52
mmm, ho provato a compilarlo... un esempio 5-7 , stampando num2 infatti non è un numero ma è una stringa formata da "-7", quindi con quel codice non era sicuro che num1 e num2 siano numero. CVD

-fidel-
12-05-2007, 11:28
mmm, ho provato a compilarlo... un esempio 5-7 , stampando num2 infatti non è un numero ma è una stringa formata da "-7", quindi con quel codice non era sicuro che num1 e num2 siano numero. CVD

non proprio ;)

Prova questo codice:


#include <iostream>

using namespace std;

int main()
{
int operands[2];

cout << "Inserisci 2 numeri interi: ";
for (unsigned char i = 0; i < 2; i++)
{
if ((cin >> operands[i] >> dec).fail())
{
cerr << "Operando " << (i + 1) << " non valido." << endl;
exit(1);
}
}
cout << "Numeri: " << operands[0] << " " << operands[1] << endl;
return 0;
}

e prova ad inserire ad esempio "5-7".
come vedi, >> converte bene. Ecco perche a lui funziona la sottrazione e la somma.
>> converte in due interi, uno positivo ed uno negativo. Nel suo programma, entra nel primo if (per forza, visto che la condizione che ha specificato è sempre vera) e fa una somma tra un numero positivo ed uno negativo (quindi una sottrazione) e va. Idem se i due numeri sono entrambi positivi, o entrambi negativi. Tra l'altro, gli altri 3 'if' neanche li vede, entra sempre nel primo e fa la somma tra i due numeri convertiti dall'operatore di estrazione >>.
Ovviamente la divisione e il prodotto non vanno, perchè le condizioni che ha specificato sono errate alla radice (il primo if lo prende sempre, quindi è sono "un caso" se funziona).

MEMon
12-05-2007, 11:30
Si hai ragione lo converte in un numero negativo :D

zergling
12-05-2007, 17:43
Hmmm, quindi come dovrebbe essere il codice?
Io per adesso ho soltanto visto IF...

-fidel-
12-05-2007, 18:03
Hmmm, quindi come dovrebbe essere il codice?
Io per adesso ho soltanto visto IF...

Se non ti offendi, cambio il nome delle variabili e rendo il tutto più compatto :)
Seguo comunque la sintassi di input da te definita prima, ma aggiungo un minimo controllo dell'input.


#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int op1, op2;
char operation;

cout << "Inserisci due numeri interi" << endl;
cout << "ad esempio 2+5 o 78-4 etc." << endl << endl;
if ((cin >> op1 >> dec).fail())
{
cerr << "Primo operando non valido." << endl;
system("PAUSE"); // Ok stai usando Windows... ;)
exit(1);
}
cin >> operation;
if ((cin >> op2 >> dec).fail())
{
cerr << "Secondo operando non valido." << endl;
system("PAUSE");
exit(1);
}

switch(operation)
{
case '+':
cout << "= " << (op1 + op2) << endl;
break;
case '-':
cout << "= " << (op1 - op2) << endl;
break;
case '*':
cout << "= " << (op1 * op2) << endl;
break;
case '/':
cout << "= " << (op1 / op2) << endl;
break;
default:
cout << "Operazione non valida." << endl;
}
system("PAUSE");
return EXIT_SUCCESS; // anche return 0 va bene.
}


EDIT: in fase di test, prova anche a dargli input "particolari", tipo -5--8, oppure a separare con degli spazi, tipo 20 / 4

-fidel-
12-05-2007, 18:14
Scusami non avevo visto che finora hai studiato solo 'if'. Ok, riposto il programma usando if:


#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
int op1, op2;
char operation;

cout << "Inserisci due numeri interi" << endl;
cout << "ad esempio 2+5 o 78-4 etc." << endl << endl;
if ((cin >> op1 >> dec).fail())
{
cerr << "Primo operando non valido." << endl;
system("PAUSE"); // Ok stai usando Windows... ;)
exit(1);
}
cin >> operation;
if ((cin >> op2 >> dec).fail())
{
cerr << "Secondo operando non valido." << endl;
system("PAUSE");
exit(1);
}

if (operation == '+')
cout << "= " << (op1 + op2) << endl;
else if (operation == '-')
cout << "= " << (op1 - op2) << endl;
else if (operation == '*')
cout << "= " << (op1 * op2) << endl;
else if (operation == '/')
cout << "= " << (op1 / op2) << endl;
else
cout << "Operazione non valida." << endl;

system("PAUSE");
return EXIT_SUCCESS; // anche return 0 va bene.
}


Nota che quando un blocco 'if' contiene una sola riga di codice, puoi omettere le parentesi graffe.
Certo, nessuno ti vieta di fare:


if (operation == '+')
{
cout << "= " << (op1 + op2) << endl;
}
else if (operation == '-')
{
cout << "= " << (op1 - op2) << endl;
}
else if ...

ma secondo me è meno leggibile, perchè rende il sorgente inutilmente più lungo (poi personalmente cose del tipo:
if (condizione) {
una sola riga di codice; }
non le sopporto :D

zergling
13-05-2007, 19:10
Ciao -Fidel-
Finalemnte grazie al vostro aiuto e consigli ho finalmente capito dove sbagliavo.
Ho fatto un mischione tra IF e Case perche ho visto nel penultimo esempio di -Fidel- che il mio codice sorgente e' veramente simile al "Case".

Avrei bisogno di un ultima delucidazione da parte tua -Fidel-.
Che cosa fa questa cosa ? dec).fail()

Ciao e grazie a tutti per il vostro aiuto :)

-fidel-
13-05-2007, 19:37
Ciao -Fidel-
Finalemnte grazie al vostro aiuto e consigli ho finalmente capito dove sbagliavo.
Ho fatto un mischione tra IF e Case perche ho visto nel penultimo esempio di -Fidel- che il mio codice sorgente e' veramente simile al "Case".

Avrei bisogno di un ultima delucidazione da parte tua -Fidel-.
Che cosa fa questa cosa ? dec).fail()

Ciao e grazie a tutti per il vostro aiuto :)

Semplice: con "dec" dico a c++ di trattare la variabile come un valore numerico (qualunque esso sia: intero, non intero (float), negatico, ecc). Quindi con:

cin >> op1 >> dec

dico a c++ di prendere da tastiera il primo valore che incontra, metterlo in op1 e trattarlo (forzarlo) come un numero decimale (in base 10), del tipo definito dalla variabile che conterrà il valore (int, float, double, ecc.) . Come puoi immaginare, non è assolutamente detto che questa operazione vada a buon fine (magari ho inserito delle lettere invece che dei numeri, oppure ho inserito un numero tipo 10,4 ma op1 è di tipo "int" e non "float", ecc.). Nel caso l'operazione non vada a buon fine, l'operatore >> setta un bit di errore interno, chiamato failbit: controllando quindi il valore di questo bit, si può sapere se l'operazione è andata a buon fine oppure no: è come un valore di ritorno dell'operatore >>. Per controllare se il failbit è stato settato (quindi c'è stato un errore) uso il metodo "fail()" dello stream: se esso ritorna "true" significa che il failbit è stato settato (è a 1) e quindi c'è stato un errore, di conseguenza entro nell'if, dove segnalo l'errore ed esco.

In pratica, con una riga di codice, ho fatto un controllo dei dati presi da tastiera ;)

Se vuoi saperne di più su "dec" dai un'occhiata qui (vedrai che non esiste solo dec :)):

http://www.cplusplus.com/reference/iostream/manipulators/dec.html