Hoe voorkom ik dat mijn programma rare dingen doet als in plaats van een getal een letter wordt ingetypt?

© Harry Broeders.

Deze pagina is bestemd voor studenten van de Haagse Hogeschool - Academie voor Technology, Innovation & Society Delft.

Hoe voorkom ik dat mijn programma rare dingen doet als in plaats van een getal een letter wordt ingetypt?

Als je in C programma een getal inleest met scanf dan gebeuren er vreemde dingen als je in plaats van een getal letters intypt.

Bijvoorbeeld:

#include <stdio.h>

int main(void) {
    int getal;
    char afval;
    printf("Geef een geheel getal: ");
    scanf("%d%c", &getal, &afval);
    printf("Het getal is %d.\n", getal);
    printf("Druk op de Enter toets om dit window te sluiten.");
    getchar();
    return 0;
}

Als je dit programma uitvoert en als invoer het woord Hallo intypt dan verschijnt de volgende uitvoer:

Geef een geheel getal: Hallo
Het getal is -858993460.
Druk op de Enter toets om dit window te sluiten.

Oplossing 1:

Dit kun je vrij eenvoudig voorkomen door de returnwaarde van de functie scanf te testen. Deze functie geeft de integer waarde EOF terug als er iets fout gaat bij het inlezen. Anders geeft de functie het aantal variabelen terug dat succesvol is geconverteerd en ingelezen.

Voorbeeld:

#include <stdio.h>

int main(void) {
    int getal, ret;
    do {
        printf("Geef een geheel getal: ");
        ret=scanf("%d", &getal);
        if (ret == 0) {
            printf("Dat was geen getal!\n");
            printf("Maar het karakter %c.\n", getchar());
        }
        else if (ret == EOF) {
            printf("Er is een fout opgetreden bij het lezen!\n");
        }
    } while (ret != 1);
    printf("Het getal is %d.\n", getal);
    printf("Druk op de Enter toets om dit window te sluiten.");
    fflush(stdin);
    getchar();
    return 0;
}

Als je dit programma uitvoert en als invoer het woord Hallo intypt dan verschijnt de volgense uitvoer:

Geef een geheel getal: Hallo
Dat was geen getal!
Maar het karakter H.
Geef een geheel getal: Dat was geen getal!
Maar het karakter a.
Geef een geheel getal: Dat was geen getal!
Maar het karakter l.
Geef een geheel getal: Dat was geen getal!
Maar het karakter l.
Geef een geheel getal: Dat was geen getal!
Maar het karakter o.
Geef een geheel getal:

Als je daarna het getal 23 invoert dan verschijnt de uitvoer:

Geef een geheel getal: 23
Het getal is 23.
Druk op de Enter toets om dit window te sluiten.

Oplossing 2:

Het bij oplossing 1 gegeven programma geeft als je een woord intypt voor elke letter een aparte foutmelding. Dat is een beetje overdreven. Je kunt dit voorkomen door voordat je scanf aanroept alle nog aanwezig invoer weg te gooien door fflush(stdio) aan te roepen. Het bij oplossing 1 gegeven programma maakt als het inlezen niet lukt nog onderscheid tussen een leesfout en verkeerde invoer. Vaak willen we de scanf net zolang herhalen totdat het inlezen is gelukt zonder dat we er in geïnteresseerd zijn waarom het niet lukt.

#include <stdio.h>

int main(void) {
    int getal;
    do {
        printf("Geef een geheel getal: ");
        fflush(stdin);
    } while (scanf("%d", &getal) != 1);
    printf("Het getal is %d.\n", getal);
    printf("Druk op de Enter toets om dit window te sluiten.");
    fflush(stdin);
    getchar();
    return 0;
}

Als je nu achtereenvolgens het woord Hallo en het getal 23 invoert dan geeft het programma de volgende output:

Geef een geheel getal: Hallo
Geef een geheel getal: 23
Het getal is 23.
Druk op de Enter toets om dit window te sluiten.

Zeer uitgebreide informatie over de functie scanf kun je vinden op: http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html.