Newsgroup: it.comp.lang.c
Titolo: perche' non va? (molto semplice)

Non capisco come mai non funzioni questo programmino (se tolgo l' 'if' nella
main(), funziona)
#include <stdio.h>
char memchar();
void pippo();
main()
{
    char c;
    printf("digita x\n");
    if(c=memchar()=='x')
    pippo();
}
void pippo()
{
    char c;
    printf("digita h\n");
    if(c=memchar()=='h')
    printf("OK\n");
}
char memchar()
{
    char c;
    scanf("%c",&c);
    return c;
}
Ci sono molte porcherie? (a parte il fatto che non funziona)
Poi ho scritto una funzione che memorizza stringhe dalla tastiera e le mette
su un vettore:
char memstringa()
{
    char *c;
    char buff[1024];
    c=buff;
    scanf("%s",&buff);
    return c;
}
anche qua' ci son molte porcherie? (anche se funziona)
Grazie mille.

 }
.........................
........................
Ciao cacciavite, immagino tu intenda che non funziona in quanto, una volta 
schiacciato x, il tuo prog sembra saltare pippo.
nota: pippo mettilo in una posizione in cui risulti piu' ovvio, per l'occhio 
umano, che e' conseguenza dell'if
Ci sono due problemi.
Il primo e' che tu, per fargli accettare 'x', devi premere invio (perche' 
scanf() funziona così).
Quindi il tuo programma memorizza 'x' e lascia il carattere di newline 
(invio) nel buffer di tastiera.
Quando c'e' un'altra scanf(), la scanf guarda se c'e' qualcosa nel buffer, 
trova il carattere di newline e lo pappa.
Il secondo problema e' che tu non dai alternative all'if di pippo();
Quindi se il carattere non e' h al posto di scriverti OK lui....va avanti e 
chiude il prog, senza dirti nulla.
Soluzioni.
Tra le varie soluzioni, abbiamo:
utilizzare getchar() al posto di scanf() - prende il primo carattere 
presente nel buffer e prosegue - 
oppure modificare
if(c=memchar()=='h')
con
while(c=memchar()!='h');
in questo modo finche' il carattere immesso e' diverso da 'h' 
lui....ricontrolla.
Mi sembra che l'altra funzione, quella con la stringa, vada bene, ma non la 
puoi inserire nel programma, in quanto il programma controlla uguaglianze 
di singoli caratteri e non di stringhe.
Ciao,
Riccardo

 lui....ricontrolla.
Grazie per le correzzioni che mi hai fatto .
Ti spiego un attimo cio' che dovrebbe fare il programma finale, cosi' magari
mi dai il suggerimento piu' opportuno. In pratica il prog. deve interagire
con l'utente chiedendogli di digitare dei caratteri, e a seconda del
carattere dgtato viene chiamata una certa funzione. Da qui' la necessita' di
una serie di if che controllano il carattere digitato dall'utente e lo
associano alla funzione corrispondente (quindi una serie di :
if(c=memchar()=='x')  pippo(); ).
Il problema e' che come tu mi hai detto (io non lo sapevo, o manco ci avevo
pensato) la locazione di memoria nella quale la scanf memorizza il valore
del carattere rimane "occupata" dal carattere di newline e quindi tutti i
successivi if  verrebbero ignorati (a meno che non ce ne fosse uno che
compara con '\n', giusto? ;) ).
Non so ci vorrebbe un modo per "ripulire" quella locazione di memoria forse,
tipo il free dei puntatori....
Grazie Cacciavite.

> lui....ricontrolla.
Con questa soluzione tu memorizzi in C un valore booleano
corrispondente a zero o uno a seconda del risultato di memchar() !=
'h', poiche' l'assegnamento ha una precedenza minore rispetto agli
operatori di confronto... sei sicuro che fosse questo lo scopo?
Riscrivi il tutto come 
if ( (c=memchar()) != 'h' )
Il nome memchar e' molto simile a quello di una funzione di libreria
memchr() che tra l'altro fa una cosa diversa, ti converrebbe
sceglierne uno piu' significativo. Ovviamente e' un consiglio e non
influisce in nessun modo sulla correttezza o meno del programma.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 Grazie Cacciavite.
Da quel che scrivi mi sembra ti convenga usare switch(). E' di sicuro una 
soluzione piu' elegante che usare molte if.
dato che mox aveva ragione, ho messo una if per evitare lo '\n' nell'esempio 
seguente
#include <stdio.h>
int main(void)
{
int c;
inizio:
printf("Opzione 'a': faccio questo e quest'altro\n");
printf("Opzione 'b': faccio quello e quell'altro\n");
if(c=getchar()=='\n') c=getchar();
switch(c)
        {
        case 'a': printf("Hai schiacciato 'a' e ora parte il codice 
seguente\n");
                  break;
        case 'b': printf("Ora verra' eseguito il codice associato alla 
scelta'b'");
                  break;
        default:  printf("Non hai scelto nessuna opzione valida. 
Riprova\n");
                  goto inizio;
        }
exit(0);
}
ciao,
Riccardo

if(c=getchar()=='\n') c=getchar();
Continua a esserci l'errore sulla precedenza degli operatori pero'.
I cicli di input falli su questo schema:
do {
    printf("bla bla bla");      /* prompt */
    c = getchar();              /* lettura input */
    while (getchar() != '\n')   /* flush stdin */
        ;
} while (parse_input(c)); /* controlla la validita' */
E' uguale a prima, solo che contempla anche il caso in qui uno immetta
una stringa in input anziche' un singolo char (ovviamente solo nel
caso tu voglia scartare la stringa).
Avere una funzione che controlla l'input ed esegue un compito a
seconda dell'input ti costa un record di attivazione in piu', pero'
hai una maggior divisione dei compiti e ti eviti di dover fare tanti
controlli uguali in vari punti.
int parse_input (int c)
{
switch(c) {
    case 'a':
        printf("Hai premuto 'a'\n");
        funzione_a();
        return 1;
    case 'b':
        printf("Hai premuto 'b'");
        funzione_b();
        return 1;
    default:
        printf("Non hai scelto nessuna opzione valida. Riprova\n");
        return 0;
