Errore nella scanf("%d")

di il
2 risposte

Errore nella scanf("%d")

Ciao a tutti, vi spiego brevemente il mio problema. Ho scritto il gioco del tris tra due giocatori in ANSI C, il programma funziona correttamente, ma ci sarebbero delle finezze che vorrei apportare.
/*****************************/
/* Inclusione delle librerie */
/*****************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
	
/********************************/
/* Dichiarazione delle funzioni */
/********************************/

void disegna_grafico(char[3][3],
		     int);
int inizia_partita(char[3][3],
	  	   int*,
	  	   int,
	  	   int);
void popola_matrice(char[3][3]);
int gestione_vittoria(char[3][3],
		      char);

/* Definizione della funzione main */

int main ()
{	
	/* Definizione delle variabili locali alla funzione */
        char tris[3][3];			/* Output: Matrice 3x3 del tris*/

	int inserimenti = 0;			/* Lavoro: Variabile che aggiorna quanti inserimenti sono stati effettuati */
	int valido = 0;				/* Lavoro: Variabile flag per determinare la fine della partita */
	
	int inizio = 0;				/* Lavoro: Variabile che gestisce casualmente l'inizio della partita */

	/* Popola la matrice tris con degli spazi */
	popola_matrice(tris);

	/* Si richiama la funzione che stampa a video la matrice tris */
	disegna_grafico(tris,inserimenti);

	/* Si gestisce in modo casuale quale giocatore deve iniziare */
        srand(time(NULL));
        inizio = rand() % 2;

        printf("\nSta per iniziare la partita, tenetevi pronti!\n");

        if(inizio == 0)
                printf("\nIl giocatore X è il primo ad iniziare.\n\n");
        else
                printf("\nIl giocatore O è il primo ad iniziare.\n\n");

        /* Se il risultato della funzione rand() è 0, allora inizia il giocatore X */
        do
        {
                valido = inizia_partita(tris,&inserimenti,valido,inizio);
		inizio = (inizio + 1) % 2;
        }
        while(valido != 1);

	return (0);
}

/* Definizione della funzione disegna_grafico */

void disegna_grafico(char tris[3][3],
		     int inserimenti)
{
	int i,			/* Lavoro: Variabile che scorre le righe della matrice */
	    j;			/* Lavoro: Variabile che scorre le colonne della matrice */
  	
	/* All'inizio della partita... */
	if(inserimenti == 0)
		printf("Disegno il campo da gioco...\n");

	printf("\n    0  1  2  ");
	printf("\n    __ __ __ ");

	for(i=0;i<3;i++)
       	{
		printf("\n");
		printf("%d  |",i);
		printf("_");
		/* All'inizio della partita... */
		if(inserimenti == 0) 
		{
               		for(j=0;j<3;j++)
               		{
				if(j == 2)
					printf("_|");
				else
					printf("_|_"); 	
               		}
       		}
		else
		{
			for(j = 0; j < 3; j++)	
			{
				if(j == 2)
					printf("%c|",tris[i][j]);
				else
					printf("%c|_",tris[i][j]);
			}
		}
	}
        
	printf("\n\n");
}

/* Definizione della funzione popola_matrice */

void popola_matrice(char tris[3][3])
{
	int i,			/* Lavoro: Variabile che scorre le righe della matrice */
	    j;			/* Lavoro: Variabile che scorre le colonne della matrice */
	
	/* Si popola la matrice con degli spazi vuoti */
	for(i=0;i<3;i++) 
        	for(j=0;j<3;j++)
           		tris[i][j]=' ';
}

/* Definizione della funzione inizia_partita */
			              
int inizia_partita(char tris[3][3],
	  	   int *inserimenti,
	 	   int valido,
	  	   int inizio)
{
	int prosegui = 1;		/* Lavoro: Variabile flag che gestisce se terminare o meno il programma */
	
	int  posizionex,		/* Input: Posizione orizzontale del simbolo acquisita dall'utente */
	     posizioney;		/* Input: Posizione verticale del simbolo acquisita dall'utente */

	int esito_lettura = 0;		/* Lavoro: Controllo di ritorno della funzione scanf */
	
	char simbolo;			/* Lavoro: */

	/* Associo alla variabile simbolo il valore X o O, a seconda del risultato della variabile inizio */
	if(inizio == 0)
		simbolo = 'X';
	else
		simbolo = 'O';
	do
	{
		do
		{
			printf("Scegli la posizione orizzontale di %c: ",simbolo);
			esito_lettura = scanf("%d",
					      &posizionex);
			/* Se non è stato inserito un numero valido, si richiede l'inserimento */
			if(esito_lettura != 1 || (posizionex != 0 && posizionex != 1 && posizionex != 2))
           	        {
             	        	printf("\nInput non accettabile!\n\n");
               	       		while (getchar() != '\n');
				prosegui = 0;
               	       	}
			else
			{
				prosegui = 1;
				while(getchar() != '\n');
			}
		}
		while(prosegui != 1);
		do
		{
			printf("Scegli la posizione verticale di %c: ",simbolo);
			esito_lettura = scanf("%d",
					      &posizioney);
			/* Se non è stato inserito un numero valido, si richiede l'inserimento */
			if(esito_lettura != 1 || (posizioney != 0 && posizioney != 1 && posizioney != 2))
               	        {
        	                printf("\nInput non accettabile!\n\n");
				while (getchar() != '\n');
               	       		prosegui = 0;
			}
			else
			{	
				prosegui = 1;
				while (getchar() != '\n');
			}
		}
		while(prosegui != 1);
		/* Si impedisce all'utente di sovrascrivere le caselle della matrice già occupate */
		if(tris[posizionex][posizioney] == 'X' || tris[posizionex][posizioney] == 'O')
		{
			printf("\nQuesta posizione è già stata assegnata! Inserisci una posizione valida.\n\n");
			prosegui = 0;
		}
		else
		{
			prosegui = 1;
		}		
	}		
	while(prosegui != 1);
	tris[posizionex][posizioney] = simbolo;
	*inserimenti += 1;
	disegna_grafico(tris,*inserimenti);
	/* Controlla se il giocatore X ha vinto, se sì... */
	if(gestione_vittoria(tris,simbolo) == 1)
		/*...imposta valido = 1,così da non chiedere altri inserimenti */
		valido = 1; 
	/* Se nessun giocatore ha avuto la meglio sull'altro... */
	if(*inserimenti == 9)
	{
		printf("\nLa partita termina in pareggio!\n");
		valido = 1;
	}
	
	return(valido);
}

/* Definizione della funzione gestione_vittoria */

int gestione_vittoria(char tris[3][3],
		      char simbolo)
{
	int i;
	
	/* Controllo tutte le possibili situazioni di vittoria */
	for(i = 0; i < 3; i++)
	{
		if((tris[0][i] == simbolo && tris[1][i] == simbolo && tris[2][i] == simbolo) ||
			(tris[i][0] == simbolo && tris[i][1] == simbolo && tris[i][2] == simbolo) ||
			(tris[0][0] == simbolo && tris[1][1] == simbolo && tris[2][2] == simbolo) ||
			(tris[0][2] == simbolo && tris[1][1] == simbolo && tris[2][0] == simbolo))
		{	
			printf("\nIl giocatore %c ha vinto!\n",simbolo);
			printf("\nLa partita è terminata...\n");
			return 1;
		}
	}

	return(0);
}
Praticamente il mio programma funziona e nel momento della richiesta dell'input non vengono accettati caratteri o numeri diversi da 0,1,2, come è giusto che sia. Il problema si presenta nel momento in cui effettuo un inserimento del tipo 0ciao, oppure 0001. Il primo caso il programma non lo considera come errore, prende il numero 0 in memoria e poi svuota il buffer, quindi la stringa ciao viene buttata via, ma io preferirei che il programma notificasse l'errore e richiedesse l'inserimento. Nel secondo caso invece il programma prende per buono il numero 1, ma anche qui vorrei che venisse considerato errore. Avete qualche idea su come risolvere questi due casi? Probabilmente sono delle sciocchezze, ma non ho proprio idea di come risolvere.. ho provato anche a usare la getchar e a convertire il carattere in numero, ma in quel caso risolverei soltanto il secondo caso. Aspetto vostre notizie, grazie.

2 Risposte

  • Re: Errore nella scanf("%d")

    Il C (ma anche il C++) non sono "evoluti" dal punto di vista dell'input.

    Usa una stringa per il tuo input e scrivi una tua funzione per il controllo, carattere per carattere, del dato inserito.

    Se lo ritieni valido, lo converti in valore intero e lo accetti.
  • Re: Errore nella scanf("%d")

    Provo il prima possibile, grazie mille per il consiglio!
Devi accedere o registrarti per scrivere nel forum
2 risposte