PROBLEMA funzione fgets

U

Utente cancellato 359755

Ospite
Salve a tutti, ho scritto un programma dove è possibile "organizzare" un'agenda. Affinché fosse possibile inserire anche lo spazio ho usato la funzione fgets che confesso di non aver compreso bene. Vi chiedo il favore di "spiegarmi" se possibile, ovviamente come si utilizza la funzione e il perché il programma mi salta la richiesta relativa al Titolo Appuntamento e salta a Descrizione Appuntamento.
Allego parte del codice
C:
int main() {
    int hh, mm, me, g, i;
    char strtmp[100];
    char strtmp2[300];
    Agenda Anno2020;
            printf("Il programma crea un'agenda e riodina gli impegni per data.\nQuando non si vogliono piu' inserire impegni inserire come giorno 32\n");
    while (g!=32){
        printf("\nInserire il giorno dell'appuntamento ");
            scanf("%d", &g);
                Anno2020.numero[i].n_giorno=g;
        if(g!=32){
        printf("Inserire il mese dell'appuntamento ");
            scanf("%d", &me);
                Anno2020.numero[i].mese=me;
        printf("Inserire a che ora c'e' l'appuntamento nel formato hh ");
            scanf("%d",&hh);
                Anno2020.numero[i].ora=hh;
        printf("Inserire a che minuto dell'appuntamento nel formato mm ");
            scanf("%d", &mm);
                Anno2020.numero[i].minuti=mm;
        printf("Inserire il Titolo dell'appuntamento ");
            fgets(&strtmp, 100, stdin);
                strcpy(Anno2020.numero[i].TitoloAppuntamento,strtmp);
        printf("Inserire una descrizione dell'appuntamento ");
            fgets(&strtmp2, 300, stdin);
                strcpy(Anno2020.numero[i].DescrizioneAppuntamento, strtmp2);
    i++;   
    }
}
BubbleSort_me(Anno2020.numero, i);
stampa (Anno2020, i);
        
    system ("PAUSE");
    return 0;
}
 

DispatchCode

Utente Attivo
795
507
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Internet
30Mbps/3Mbps con Eolo
Sistema Operativo
Windows 10 64bit
Il programma ti salta la richiesta perchè rimane nel buffer un carattere di "new line" lasciato da scanf
In sostanza quando digiti qualcosa e premi invio, questo viene mantenuto nel buffer; fgets() va a leggere il buffer e si interrompe quando trova un "new line"... solo che essendo sporco (appunto, dalla presenza del new line) si interrompe subito (perchè è come se avessi premuto Invio).

Dovresti utilizzarlo prima della scanf, oppure evitare di combinarlo con la scanf (o ancora, puoi fare un flush del buffer ad esempio).
 
  • Mi piace
Reactions: Andretti60
U

Utente cancellato 359755

Ospite
Quindi mi basta aggiungere un fflush(stdin); per risolvere il problema la quale mi "pulisce" stdin?
 

DispatchCode

Utente Attivo
795
507
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Internet
30Mbps/3Mbps con Eolo
Sistema Operativo
Windows 10 64bit
Aggiungi a scanf un \n dopo alla d (o metti uno spazio). Dovrebbe venir consumato già dalla scanf.
Puoi anche leggere un carattere dopo la scanf... anche se non è proprio pulito come metodo.

L'utilizzo di fflsuh con stdin non sarebbe da fare (undefined behavior).
 
  • Mi piace
Reactions: fabio93
U

Utente cancellato 359755

Ospite
Facendo così mi succede che non esce il printf ma mi fa prima inserire i dati inerenti Titolo Appuntamento e poi lo visualizza. Allego immagine per maggiore comprensione
 

Allegati

  • 168 KB Visualizzazioni: 10

DispatchCode

Utente Attivo
795
507
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Internet
30Mbps/3Mbps con Eolo
Sistema Operativo
Windows 10 64bit
Usa esplicitamente \n.
 

DispatchCode

Utente Attivo
795
507
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Internet
30Mbps/3Mbps con Eolo
Sistema Operativo
Windows 10 64bit
Ma che compilatore stai utilizzando?
 

Andretti60

Utente Èlite
3,928
2,654
Mischiare gets() e scanf() è pericoloso ed è una pratica da evitare (come pure getchar)
La cosa migliore da fare quando di legge in file (o anche da terminale) è di usare fgets() leggendo una linea alla volta, memorizzare tutta la linea in una stringa temporanea e poi usare sscanf() per leggere i vari componenti (e avere quindi modo anche di controllare possibili errori di formattazione).
Il problema è causato da quei orribili caratteri di ritorno (che a volte sono due a seconda del sistema operativo), ”scartarli” a mano produce code poco trasportabile e che può facilmente causare errori.
 
  • Mi piace
Reactions: DispatchCode
U

Utente cancellato 359755

Ospite
e quindi scusami, non riesco a capire. Dovrei sostituire le scanf con tutte fgets anche se sono variabili semplici, ossia numeri?
grazie
 

Andretti60

Utente Èlite
3,928
2,654
Si, usi solo gets() o solo scanf()
Non mischiarle.
È una delle cose che si impara subito quando di studia IO del vecchio linguaggio C. Analogo a non mischiare read() con fread(). Crea solo problemi, credimi.
 
U

Utente cancellato 359755

Ospite
facendo così invece il programma "impazzisce" e non esce più neanche dal ciclo while
d.PNG
 

DispatchCode

Utente Attivo
795
507
CPU
Intel i7 6700HQ, 2.60Ghz, 4 core 8 threads
Scheda Madre
Asustek
Hard Disk
Hitachi 7200 rpm, 1TB
RAM
16GB DDR4 (2 slot su 4)
Scheda Video
Nvidia Geforce GTX 960M, 4GB
Scheda Audio
Realtek
Internet
30Mbps/3Mbps con Eolo
Sistema Operativo
Windows 10 64bit
Ora che ci faccio caso, come condizione del while stai usando 'g', ma incrementi 'i'.
Per altro 'i' non è inizializzata, quindi avrà un valore "randomico". Questo è sicuramente un errore già di per sè.
 
  • Mi piace
Reactions: _Achille

_Achille

Utente Èlite
3,065
722
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
Hard Disk
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
Scheda Video
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
Alimentatore
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
Sistema Operativo
Windows 10 Pro
Ora che ci faccio caso, come condizione del while stai usando 'g', ma incrementi 'i'.
Per altro 'i' non è inizializzata, quindi avrà un valore "randomico". Questo è sicuramente un errore già di per sè.
Nemmeno g è inizializzato.
Correttamente, il ciclo dovrebbe essere un do - while

E ogni tanto qualche riga vuota si può lasciare quando è giusta… tanto da capirci qualcosa…
 
  • Mi piace
Reactions: DispatchCode

Entra

oppure Accedi utilizzando

Discussioni Simili

Hot del momento