Newsgroup: it.comp.lang.c
Titolo: Scanf e caratteri superflui

Salve a tutti.
Io ho un piccolo problema, certamente derivante dal fatto che non ho una
conoscenza approfondita del linguaggio C, ma che vi serei grato mi aiutaste
a risolvere.
Per un programma che deve chiedere il giorno della settimana e, acquisitolo,
deve chiedere l'orario per le singole ore, io ho scritto questo:
#include<stdio.h>
#include<conio.h>
#include<string.h>
char scelta[10],flag;
int i,youbi;
int controllo_giorni(char *day);
int controllo_materia(char *mater);
void inserimento();
int controllo_giorni(char *day){
    char day2[10];
    strcpy(day2,day);
        if(strcmp(day2,"lunedi")==0){
            youbi=1;
            return(0);
            }
        if(strcmp(day2,"martedi")==0){
            youbi=2;
            return(0);
            }
        if(strcmp(day2,"mercoledi")==0){
            youbi=3;
            return(0);
            }
        if(strcmp(day2,"giovedi")==0){
            youbi=4;
            return(0);
            }
        if(strcmp(day2,"venerdi")==0){
            youbi=5;
            return(0);
            }
        if(strcmp(day2,"sabato")==0){
            youbi=6;
            return(0);
            }
        printf("\n\nIl giorno immesso non è stato riconosciuto.
Riprovare.");
        getch();
        return(1);}
struct giorno {
    char prima[25];
    char seconda[25];
    char terza[25];
    char quarta[25];
    char quinta[25];
    char sesta[25];};
struct giorno settimana[7];
int controllo_materia(char *mater){
    char materia[25];
    strcpy(materia,mater);
    if(strcmp(materia,"matematica")==0) return(0);
    if(strcmp(materia,"filosofia")==0) return(0);
    if(strcmp(materia,"scienze")==0) return(0);
    if(strcmp(materia,"biologia")==0) return(0);
    if(strcmp(materia,"fisica")==0) return(0);
    if(strcmp(materia,"ginnastica")==0) return(0);
    if(strcmp(materia,"chimica")==0) return(0);
    if(strcmp(materia,"inglese")==0) return(0);
    if(strcmp(materia,"storia")==0) return(0);
    if(strcmp(materia,"italiano")==0) return(0);
    if(strcmp(materia,"informatica")==0) return(0);
    printf("\n\nLa materia inserita non è valida.");
    getch();
    return(1);}
void inserimento(){
    do{
        clrscr();
        printf("Inserire l'orario della prima ora: ");
        scanf("%25s",settimana[youbi].prima);
    }while(controllo_materia(settimana[youbi].prima)==1);
    do{
        clrscr();
        printf("Inserire l'orario della seconda ora: ");
        scanf("%25s",settimana[youbi].seconda);
    }while(controllo_materia(settimana[youbi].seconda)==1);
    do{
        clrscr();
        printf("Inserire l'orario della terza ora: ");
        scanf("%25s",settimana[youbi].terza);
    }while(controllo_materia(settimana[youbi].terza)==1);
    do{
        clrscr();
        printf("Inserire l'orario della quarta ora: ");
        scanf("%25s",settimana[youbi].quarta);
    }while(controllo_materia(settimana[youbi].quarta)==1);
    do{
        clrscr();
        printf("Inserire l'orario della quinta ora: ");
        scanf("%25s",settimana[youbi].quinta);
    }while(controllo_materia(settimana[youbi].quinta)==1);
    do{
        clrscr();
        printf("Inserire l'orario della sesta ora: ");
        scanf("%25s",settimana[youbi].sesta);
    }while(controllo_materia(settimana[youbi].sesta)==1);  }
void scrivi_ora(){
    printf("1a ora:\t%s\n",settimana[youbi].prima);
    printf("2a ora:\t%s\n",settimana[youbi].seconda);
    printf("3a ora:\t%s\n",settimana[youbi].terza);
    printf("4a ora:\t%s\n",settimana[youbi].quarta);
    printf("5a ora:\t%s\n",settimana[youbi].quinta);
    printf("6a ora:\t%s",settimana[youbi].sesta);
    }
void main(){
do{
    do{
        clrscr();
        printf("Scegli un giorno della settimana:\t");
        scanf("%10s",scelta);
    }while(controllo_giorni(scelta)==1);
    printf("Ora dovrai inserire l'orario...premere un tasto per
continuare.");
    getch();
    inserimento();
    clrscr();
    printf("L'orario inserito e':\n\n");
    scrivi_ora();
    do{
     printf("\n\nConfermi? (s/n)\n");
     scanf("%s1",&flag);
    }while((flag!='s')&&(flag!='n'));
}while((flag!='s'));}
Il mio esercizio, perchè ovviamente di questo si tratta, dovrebbe essere
molto più semplice, ma io ho deciso di fare qualche passo avanti...
Adesso, il problema che mi si presenta è che quando devo inserire il giorno
della settimana ed assegnarlo ad una stringa, i dati che rimangono non
assegnati vengono mantenuti per lo scanf sucessivo, sia esso nello stesso
controllo (per esempio se sbaglio il nome del giorno) o in una parte
sucessiva del programma (quando inserisco il giorno corretto, il primo ciclo
per l'inserimento della materia risulta errato).
Non so se mi sono spiegato, ma sono sicuro che tutto dipende dal mio
utilizzo di scanf e dal mancato "svuotamento" dei dati non assegnati alla
stringa "scelta".
Inoltre, tanto che ci sono vi volevo anche chiedere se non esiste un
sistema, mantenendo il controllo sul numero di caratteri assegnati alla
stringa, di assegnare a "scelta" un input in cui ci siano degli spazi
(scanf, per quello che ne so io ritiene lo spazio il termine di una
stringa).
Grazie a tutti coloro che mi vorranno aiutare
Saluti
p.s. L'array di strutture che si vede nel programm servirà più avanti nella
realizzazione dell'esercizio....
p.p.s Qualunque consiglio, critica e suggerimento sarà gradito, ri-grazie.
p.p.p.s. Scusate per il messaggio un po' lungo, forse immotivatamente....

Ho un problema analogo: in sostanza il '\n' impartito per effettuare
un'assegnazione tramite scanf non viene scartato ma viene processato
dalla scanf successiva. Ho aggirato il problema utilizzando una
stringa e successivamente le funzioni "atoi", "atol" o all'occorrenza
"strtoi" "strtol" se devo fare conversioni particolari, però mi sembra
una soluzione barocca, e di fatto fa sembrare scanf una funzione
pressocché inutile, sicuramente sbaglio qualcosa nell'utilizzare
scanf ma dopo svariate prove non ho trovato soluzioni migliori.

        /* Nothing */;
EOF a carico tuo :P
Luca
-- 
Home: 
http://kronoz.cjb.net
Tentare e` il primo passo verso il fallimento.
Homer J. Simpson

 dalla scanf successiva. ...
E tu elimina il \n. In genere la miglior ricetta per convivere con le 
scanf e'  di non mettere nulla tranne i descrittori di formato (niente 
spazi, niente virgole, niente \n...).
Questo finche'  le cose sono semplici. Se si complicano, meglio metter 
su  una gestione autonoma e personalizzata dell' input.
Giorgio

Ti dirò, quando cominciavo a sentirmi un po' scafato con il C scoprirmi in
difficoltà di fronte ad una funzione che legge input dalla tastiera ha
parecchio ridimensionato la mia esuberanza. Cacchio, il C ti insegna l'umiltà.
Ieri me ne è successa un'altra, và, te la racconto. Avevo dichiarato due variabili:
     unsigned char data;
     unsigned int  address;
Assegnavo loro dei valori con scanf:
     scanf("0x%X", &address);   // i valori glieli formatto in esadecimale 
     scanf("0x%X", &data);      // perché mi servono così.
Naturalmente l'acquisizione di /data/ va ad invadere la memoria
assegnata ad /address/, ma prima di arriverci...
Ciao.

 pressocché inutile
In effetti lo e`[1] ;) Il problema dalla scanf e` che lascia il buffer
dello stdin in uno stato ignoto a priori. La soluzione comunemente
adottata e` quella di acquisire un'intera linea all'interno di un buffer
e di parsare quello. In questo modo si e` sicuri che le letture
successive partiranno da una riga nuova.
Se il problema e` solo il newline vagante la soluzione standard per
ignorare il newline (ed il resto della riga) e`:
while(getchar() != '\n')
        /* Nothing */;
Luca
[1] {s,f}scanf hanno piu` senso in quanto di solito operano un un input
piu` strutturato.
-- 
Home: 
http://kronoz.cjb.net
"New processes are created by other processes, just like new
 humans. New humans are created by other humans, of course,
 not by processes." -- Unix System Administration Handbook