Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2012
    Messaggi
    5

    [C] Problema con gets

    Ciao a tutti!

    mi scuso se posto una domanda già fatta, ma pur leggendo gli altri topic non riesco a trovare soluzione!

    Sto scrivendo un programma in C per l'università: è una specie di quiz, il codice è il seguente

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    #define MAX_TITLE_LEN 40
    #define MAX_Q_LEN 300
    #define MAX_A_LEN 30
    #define DEBUG
    
    int punteggio = 0;
    
    void stampa_domande (char[], FILE*, FILE*);
    void acquisisci_risposta (FILE*);
    void score (void);
    
    int main () {
    
    	int i;
    	char titolo[MAX_TITLE_LEN + 1], password[MAX_TITLE_LEN + 1];
    	char percorso_d[MAX_TITLE_LEN + 1], percorso_r[MAX_TITLE_LEN + 1], percorso_p[MAX_TITLE_LEN + 1];
    	char domanda[MAX_Q_LEN + 1];
    	char scelta;
    	FILE *d, *r, *p;
    
    		printf ("Benvenuto!\n");
    		printf ("Inserisci il titolo del film di cui vuoi le domande: ");
    		gets (titolo);
    
    		do {
    
    		for (i = 0; titolo[i] != '\0'; i++) {
    
    		   titolo[i] = tolower (titolo[i]);
    		   if (titolo[i] == ' ')
    		      titolo[i] = '-';
    		}
    
    		strcpy (percorso_d, titolo);
    		strcpy (percorso_r, titolo);
    		strcpy (percorso_p, titolo);
    		strcat (percorso_d,"/domande.txt");
    		strcat (percorso_r, "/risposte.txt");
    		strcat (percorso_p, "/password.txt");
    
    		d = fopen (percorso_d, "r");
    		r = fopen (percorso_r, "r");
    
    		if (d == NULL) {
    		   printf ("Non ho trovato il file\n");
    		   return 0;
    		}
    		else
    		   printf ("%s: ho aperto i file.\n", titolo);
    
    		while(fgets (domanda, MAX_Q_LEN, d) != NULL) 
    		   stampa_domande (domanda, d, r);
    
    		printf ("Hai totalizzato %d punti.\n", punteggio);
    
    		if (punteggio == 40 || punteggio > 40) {
    		   p = fopen (percorso_p, "r");
    		   fscanf (p, "%s", password);
    		   fclose (p);
    		   printf ("Complimenti!! Livello superato!\nLa Password per aprire l'archivio corrispondente a %s è %s\n", titolo, password);
    		}
    		else {
    		   printf ("Peccato! Livello fallito!\n");
    		   fclose (d);
    		}
    
    		printf ("Un'altra partita? (y, n) ");
    		scanf ("%c", &scelta);
    
    		if (scelta == 'y') {
    		   printf ("Inserisci il titolo del film di cui vuoi le domande: ");
    		   gets (titolo);
    
    		   #if defined (DEBUG)
    		      printf ("new_title: %s\n", titolo);
    		   #endif
    	   	}
    
    		} while (scelta != 'n');
    
    		return 0;
    
    }
    
    void stampa_domande (char domanda[], FILE *d, FILE *r) {
    
    		printf ("%s ", domanda);
    		acquisisci_risposta (r);
    
    		return;
    }
    
    void acquisisci_risposta (FILE *r) {
    
    	char risp_es[MAX_A_LEN + 1], risposta[MAX_A_LEN + 1];
    	int check;
    
    	gets (risposta);
    	fscanf (r, "%s", risp_es);
    
    	check = strcmp (risp_es, risposta);
    
    	if (check == 0) {
    	   punteggio += 10;
    	   return;
    	}
    	else
    	   return;
    }
    in pratica all'inizio del runtime l'utente specifica il nome di un film (di cui sono state caricate domande e risposte), il programma fa delle domande e l'utente risponde con risposte aperte oppure vero/falso.

    tutto ok, se non fosse che quando arrivo per la prima volta all'inizio del main e mi chiede "un'altra partita?" io faccio "y" e lui, saltando completamente la gets (titolo) in fondo termina il programma perchè non mi fa dire su quale altro film voglio essere interrogato.

    Cosa devo fare???

  2. #2
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510
    Mai usare la scanf, che ti sporca il buffer di input.
    Tutto l' input dell' utente viene messo in un' area di memoria e poi viene letto.Se l' utente digita caratteri che non vengono letti, questi rimangono nel buffer e vengono letti durante la successiva funzione di input, inquinando così il risultato.
    gets() non sporca il buffer perché legge tutti i caratteri, però ha il problema che non fa alcun controllo sulla quantità di caratteri letti, il che può causare un segmentation fault.

    In definitiva: usa solo la fgets (tieni conto del fatto che legge anche il carattere '\n'), e se vuoi leggere degli interi converti la stringa in int con atoi.

    Esempio:

    codice:
    char buffer[100];
    int num;
    puts("Digita un numero : ");
    fgets(buffer,100,stdin);
    num=atoi(buffer);

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2012
    Messaggi
    5
    ho fatto come dici tu, ma non è cambiato nulla!

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Cioè? Adesso cosa hai scritto?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510
    Tra parentesi ti sei dimenticato di copiare il terminatore nella stringa titolo:

    codice:
    for (i = 0; titolo[i] != '\0'; i++) {
    
    		   titolo[i] = tolower (titolo[i]);
    		   if (titolo[i] == ' ')
    		      titolo[i] = '-';
    		}
    titolo[strlen(titolo)]='\0';
    Comunque posta il codice che hai scritto finora.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Attenzione a linee come queste

    titolo[strlen(titolo)]='\0';

    perché, se ci rifletti un po', non hanno senso ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510
    Originariamente inviato da oregon
    Attenzione a linee come queste

    titolo[strlen(titolo)]='\0';

    perché, se ci rifletti un po', non hanno senso ...
    Hai ragione, non ci avevo pensato.La strlen non restituisce il risultato corretto perché il terminatore non c'è ancora.
    Correggo:

    codice:
    for (i = 0; titolo[i] != '\0'; i++) {
    
    		   titolo[i] = tolower (titolo[i]);
    		   if (titolo[i] == ' ')
    		      titolo[i] = '-';
    		}
                    titolo[i]='\0';

  8. #8
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    ciao

    per Who am I
    secondo me ti voleva dire , che gets() aggiunge il terminatore di riga '\0'
    gets()
    con l'istruzione :
    titolo[strlen(titolo)]='\0';
    dici sostituisci strlen(titolo) , che è il terminatore , con il terminatore


    stessa cosa per l'ultimo codice che hai postato ,
    se esce da ciclo con questa condizione titolo[i]!='\0' , è inutile questa assegnazione

    titolo[i]='\0'; , titolo[i] è gia il terminatore stringa !
    Tecnologia

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.