PDA

View Full Version : [c] mini calcolatrice con scanf


mastoo
13-08-2007, 22:19
non riesco a capire perche questo programma che dovrebbe essere una calcolatrice in notazione polacca inversa funziona , tranne che con la somma e la sottrazione
in pratica se scrivo
4 5 * =
mi da come risultato 20
10 2 / =
5
4 5 + (o meno )
comando
non conosciuto
se poi sostituisco nel prog al + un carattere qualsiasi e uso quest'ultimo per fare la somma funziona tranquillamente.
presumo che sia un problema con al console

il prog è

/*mini calcolatrice in notazione polacca post fissa con scanf*/
#include <stdio.h>

#define MAXSTACK 100

int stack[MAXSTACK];
int *sp = stack;

void push(int);
int pop(void);

main()
{
int c,val;
int op;
while((c=scanf("%d",&val))!= EOF)
if(c)
push(val);
else if(scanf("%c",&val))
switch(val)
{
case '*':
push(pop()*pop());
break;
case '+':
push(pop()+pop());
break;

case '-':
op = pop();
push(pop()-op);
break;
case '/':
op = pop();
push(pop()/op);
break;
case '=':// stampa il risultato
printf("%d",pop());
break;
default:
printf("comando '%c' non conosciuto ",val);
break;
}

}

void push(int val)
{
*sp++ = val;
}

int pop(void)
{
if(sp-1 >= stack)
return *--sp;
else
printf("stack vuoto\n");
return 0;
}

ah sotto linux

sottovento
14-08-2007, 09:18
Ciao,
non ho una macchina linux a disposizione. Ho provato con win e VS, ottenendo il tuo stesso risultato.

Ovviamente, se semplicemente ti interessa risolvere il problema, puoi sostituire la scanf(%c) con una getchar().

Ad ogni modo, mi sembra che succeda questo:
- fintanto che il numero e' corretto, scanf(%d) lo legge correttamente;
- quando inserisci un carattere, scanf(%d) FALLISCE. Il carattere e' quindi ancora nel buffer di tastiera, e la successiva scanf(%c) lo leggera' correttamente;
- quando inserisci un + od un -, scanf (%d) pensa che tu stia inserendo un NUMERO. Pertanto si aspetta che, dopo il +/-, seguano delle cifre.
Siccome non seguono, ti riporta una condizione di errore, la stessa che utilizzi per terminare il ciclo di lettura dei numeri e passare a leggere il carattere dell'operazione.
- scanf(%c) va a leggere il carattere successivo al +/-, cioe' il carattere di ritorno a capo.

E' quindi evidente che scanf() "parserizza" il suo input prima di restituirtelo.
Non e' come la getchar() la quale prende il primo carattere a disposizione e te lo restituisce: la scanf() e' piu' sofisticata.
Sembra la scanf(%d) faccia cosi:
- legge i caratteri, i quali devono essere cifre, eventualmente precedute dal segno;
- se cosi' non e', "rimetti tutto" nel buffer di input;
- se invece e' un numero mal formato (quindi un errore come quello che ti trovi), allora "rimette tutto nel buffer" ma avanza con il suo "puntatore" ai caratteri successivi, in modo da non dover piu' parsare la parte errata.

Questo spiegherebbe perche' la getchar() successiva funziona!

vegeta83ssj
14-08-2007, 10:07
Leggendo qua:
http://www.cplusplus.com/reference/clibrary/cstdio/scanf.html

il motivo per cui non ti funziona è che metti il simbolo di operazione in una variabile intera, che è:

Number optionally preceeded with a + or - sign.

quindi la scanf ti interpreta + e - come segni di un numero che però non c'è.

Ciauz

sottovento
14-08-2007, 10:10
Leggendo qua:
http://www.cplusplus.com/reference/clibrary/cstdio/scanf.html

il motivo per cui non ti funziona è che metti il simbolo di operazione in una variabile intera, che è:



quindi la scanf ti interpreta + e - come segni di un numero che però non c'è.

Ciauz

Esatto. Proprio quello che ho riportato

mastoo
14-08-2007, 10:21
grazie
ho capito il problema.
non avevo pensato che un numero puo essere preceduto da segno + e

EDIT:
ma quando la scanf(%d) fallisce il carattere + o - gia lo ha letto
quindi dopo la getchar() o la scanf(%c) leggera comunque il carattere a capo
no so come risolverlo

sottovento
14-08-2007, 10:31
grazie
ho capito il problema.
non avevo pensato che un numero puo essere preceduto da segno + e

EDIT:
ma quando la scanf(%d) fallisce il carattere + o - gia lo ha letto
quindi dopo la getchar() o la scanf(%c) leggera comunque il carattere a capo
no so come risolverlo

La prova che ho fatto, (semplicemente car = getchar() invece di scanf ("%c", &car) funzionava. Pero' l'ho fatta su un sistema diverso. Hai gia' provato?

mastoo
14-08-2007, 11:45
si ho provato cosi

.....
main()
{
int c,val;
int op;
while((c=scanf("%d",&val))!= EOF)
if(c)
push(val);
else if(val = getchar())
switch(val)
{
case '*':
push(pop()*pop());
break;
case '+':
push(pop()+pop());
break;

case '-':
op = pop();
push(pop()-op);
break;
case '/':
op = pop();
push(pop()/op);
break;
case '=':// stampa il risultato
printf("%d",pop());
break;
default:
printf("comando '%c' non conosciuto ",val);
break;
}

}
...

ma è uguale a prima