Hoe voorkom ik dat het uitvoer van mijn programma meteen verdwijnt?

© Harry Broeders.

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

Hoe voorkom ik dat het uitvoer van mijn programma meteen verdwijnt?

Als je in Microsoft Visual Studio een C programma schrijft dat uitvoer produceerd dan wordt het window waarin deze uitvoer verschijnt meteen weer gesloten. Dat is natuurlijk niet zo handig! Probeer het volgende programma maar eens te compileren en uit te voeren met Microsoft Visual Studio.

#include <stdio.h>

int main(void) {
    printf("FLITS!\n");
    return 0;
}

Als je dit programma uitvoert dan verdwijnt de uitvoer meteen. Je kunt dit oplossen door een breakpoint op de laaste regel van het programma te plaatsen maar dat wordt op den duur vervelend. Je kunt ook aan het einde van je programma het programma laten wachten tot de gebruiker een "Enter" intoetst. Je kunt hiervoor de functie getchar uit de standaard C library gebruiken. De functie getchar wacht totdat er een willekeurig karakter wordt ingetoetst en leest dit karakter in.

#include <stdio.h>

int main(void) {
    printf("FLITS!\n");
    printf("Druk op de Enter toets om dit window te sluiten.");
    getchar();
    return 0;
}

De functie getchar leest een karakter in. Deze functie start echter pas met inlezen als de gebruiker een hele regel heeft ingevoerd. Daarom moet je in dit geval op de Enter toets drukken om het uitvoerwindow te sluiten. Je kunt dus ook een hele regel intypen om het programma af te sluiten zolang je maar eindigd met een Enter.

Dit is een specifiek probleem van Microsoft Visual Studio. De gratis geïntegreerde ontwikkelomgeving Code::Blocks, zie http://www.codeblocks.org/ laat het output window gewoon open en vraagt zelf aan de gebruiker om een toets in te drukken om dit window te sluiten.

Ik gebruik getchar en toch verdwijnt mijn uitvoerwindow te vroeg. Hoe kan dat?

Als je programma niet alleen uitvoer produceert maar ook data inleest dan is het gebruik van één aanroep van getchar() niet meer voldoende! Probeer maar:

#include <stdio.h>

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

Nu sluit het window meteen nadat je het getal hebt ingetypt!

De functie scanf die het getal inleest begint pas met inlezen nadat de gebruiker op Enter heeft gedrukt. Het Enter karakter zelf wordt door de functie scanf echter niet ingelezen. De functie getchar leest dus dit Enter karakter meteen in en wacht niet op verdere invoer. Er zijn verschillende oplossingen voor dit probleem:

Oplossing 1:

Gebruik een extra aanroep getchar()om het Enter karakter dat de functie scanf nog niet heeft ingelezen alsnog in te lezen.

#include <stdio.h>

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

Oplossing 2:

Gebruik de functie fflush om alle invoer die nog niet is ingelezen weg te gooien voordat je getchar()aanroept.

#include <stdio.h>

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

Oplossing 3:

Vertel de functie scanf dat de enter na het getal ook ingelezen moet worden

#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;
}

Welke van deze 3 oplossingen is de beste?

Probeer maar eens in plaats van een getal gevolgd door een enter, een getal, dan een spatie en dan pas een enter in te voeren. Oplossing 2 is de enige oplossing die dan nog correct werkt! Oplossing 2 is dus de beste oplossing.

Volgens de C standaard mag fflush niet op een input stream gebruikt worden, zie http://en.cppreference.com/w/c/io/fflush, maar in Microsoft Visual Studio mag dit wel, zie https://msdn.microsoft.com/library/9yky46tz.aspx. Omdat we de fflush(stdin) hier gebruiken om een specifiek probleem van Microsoft Visual Studio op te lossen vind ik dit geen probleem.

Als je toch een standaard oplossing wilt dan kun je de volgende code gebruiken:

#include<stdio.h>

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