Problema in C

_Tipper
Ho scritto un programma che riceve in input da tastiera un intero n e genera casualmente n numeri.
Se n è minore o uguale a 1 la richiesta viene ripetuta con questo codice:
do
{
      printf("Inserire il numero di elementi da generare: ");
      scanf("%d", &n);
}while(n<=1);

Il problema è che se inserisco un carattere il programma mi va in loop.
Come posso fare?

Grazie

Risposte
anonymous_be1147
Prova così:
 do {
                int             s;
                printf("Inserire il numero di elementi da generare (>1): ");
                s = scanf("%d", &n);
                if (s <= 0) {
                        n = 0;
                        fpurge(stdin);
                }
} while (n <= 1);

enigmagame
Hehe :-D mi sono scontrato anche io con questo problema, prova come dice stan a controllare il valore di ritorno della scanf, se non funziona scrivi che proviamo in un altro modo...

_Tipper
Quando provo a compilare mi dice:
[Linker error] undefined reference to 'fpurge'
Le librerie che ho incluso nel programma sono: stdio.h, stdlib.h, time.h, math.h
Se provo a omettere fpurge(stdin) e a fare solo il test su s ed assegnare 0 a n il programma va ancora in loop.

enigmagame
Per fpurge bisogna includere la libreria stdio.h, ma vedo che lo hai già fatto... ora provo e ti faccio sapere...

_Tipper
Se può servire a qualcosa vi dico che uso il compilatore Dev-C++ sotto Windows XP.

_Tipper
Forse potrei usare anche la funzione atoi, in quanto la codifica avviene solo per numeri, i caratteri vengono codificati come zeri, solo che in questo caso una stringa come 100a non verrebbe vista come errore ma come 100, boh...

anonymous_be1147
Prova allora a sostituire la fpurge(stdin) con
    (void)getchar();

(Adesso non ho sotto mano XP e non l'ho provato, ma dovrebbe funzionare)

enigmagame
Io sono su Linux con GCC, con
(void)getchar()

funziona, solo che se inserisco più di un carattere mi stampa più volte il messaggio, es. se inserisco "aaa" mi stampa tre volte il messaggio.
Mi ricordo che questa cosa non ero riuscito a risolverla...

anonymous_be1147
"enigmagame":
Io sono su Linux con GCC, con
(void)getchar()

funziona, solo che se inserisco più di un carattere mi stampa più volte il messaggio, es. se inserisco "aaa" mi stampa tre volte il messaggio.
Mi ricordo che questa cosa non ero riuscito a risolverla...

Forse con
while(getchar() != '\n');

:?:

enigmagame
Esatto... è necessario un numero di
getchar()
pari al numero di caratteri inseriti. Quindi con
while(getchar() != '\n')
lo eseguo tante volte quanti i caratteri inseriti.
Confermo che funziona... :D

TIPPER prova a vedere se ti funziona

anonymous_be1147
"enigmagame":
Confermo che funziona... :D

Ok, grazie. ;)

_Tipper
Grazie ragazzi, ora funziona.
Il ciclo while(getchar() != '\n') se ho capito serve a dare il valore 0 alla variabile n tante volte quanti sono i caratteri inseriti.
Mi potreste spiegare però perché si deve inserire tale ciclo?

_Tipper
Scusate se sono tedioso ed abuso della vostra pazienza, ma se scrivo qualcosa del tipo 22r mi va in loop...

anonymous_be1147
Sì, però la variabile n viene impostata a 0 una sola volta. Il ciclo while(getchar()....) serve a "mangiarsi" tutti i caratteri in input che la scanf() non ha potuto convertire in intero.

Il codice "completo" dovrebbe apparire così:
#include <stdio.h>

int
main(void)
{
        int             n;

        do {
                int             s;
                printf("Inserire il numero di elementi da generare (>1): ");
                s = scanf("%d", &n);
                if (s <= 0) {
                        n = 0;
                        while (getchar() != '\n');
                }
        } while (n <= 1);

        return 0;
}

enigmagame
Mmmm se io inserisco una cosa del tipo "22r" non cicla ma esce, "giustamente".

eugenio.amitrano
"Tipper":
Forse potrei usare anche la funzione atoi, in quanto la codifica avviene solo per numeri, i caratteri vengono codificati come zeri, solo che in questo caso una stringa come 100a non verrebbe vista come errore ma come 100, boh...

Si potresti usare atoi in questo modo:

int n;
char buffer[SIZE];
....
....
do {
   printf("Inserire il numero di elementi da generare (>1): ");
   n = atoi(gets(buffer));
} while(n<=1);


Eugenio

anonymous_be1147
"Tipper":
Scusate se sono tedioso ed abuso della vostra pazienza, ma se scrivo qualcosa del tipo 22r mi va in loop...

:shock: In Unix funziona...

Prova allora così:

#include <ctype.h>
#include <stdio.h>

int
main(void)
{
        int             n;

        do {
                int             s         , c;
                printf("Inserire il numero di elementi da generare (>1): ");
                s = scanf("%d", &n);
                if (s <= 0) {
                        n = 0;
                        while (!isdigit(c = getchar()) && c != '\n');
                }

        } while (n <= 1);

        return 0;
}

anonymous_be1147
Un'altra soluzione:

#include <stdio.h>

int
main(void)
{
        int             n;

        do {
                int             s;
                printf("Inserire il numero di elementi da generare (>1): ");

                while(s = scanf("%d", &n) < 1 || n <= 1) {
                        printf("Input non valido!\n");
                        while(getchar() != '\n');
                        break;
                }

        } while (n <= 1);

        printf("n = %d\n", n);

        return 0;
}

anonymous_be1147
Che (volendo) può essere semplificata ulteriormente: :-D

#include <stdio.h>

int
main(void)
{
        int             n, s;

        printf("Inserire il numero di elementi da generare: ");
        while(s = scanf("%d", &n) < 1 || n <= 1) {
                printf("Input non valido! Inserire un numero maggiore di 1: ");
                while(getchar() != '\n');
        }

        printf("n = %d\n", n);

        return 0;
}

enigmagame
Hehehe :-D ce nè per tutti i gusti... :-D

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.