Jste zde

Zajímavé úlohy pro programátory v C a C++ #13

Shodou okolností jsem se dostal k zajímavému námětu na otázku, a tak toho hned využívám. Tentokrát bude úkolem vysvětlit chování programu. Zdroj otázky i původce řešení zveřejním až s uveřejněním řešení.

Zadání

Uvažujte následující program.

#include <stdio.h>
 
int main() {
    double n = .0; // Read number
    int rc;        // Return code
 
    while ((rc = scanf("%lf", &n)) != EOF) {
        printf("rc: %d, n: %lf\n", rc, n);
        if (rc == 0) {
            scanf("%*s"); // Skip invalid input
        }
    }
}

Program přeložíme:

$ gcc -std=c99 -pedantic -Wall -Wextra -g -o prog prog.c

a spustíme:

$ ./prog <<< "1 aa 2"
rc: 1, n: 1.000000
rc: 0, n: 1.000000
rc: 1, n: 2.000000
$ ./prog <<< "1 ii 2"
rc: 1, n: 1.000000
rc: 0, n: 1.000000

Úkolem je vysvětlit toto chování ;). Uvažujte C99.

Řešení

Viz komentář od wolfieho. Nápad na hádanku mám z diskusního fóra IZP v informačním systému, kde se toto řešilo. S řešením tam přišel dr. Peringer.

Komentáře

Je to tim, ze podle C99 muze scanf s %[l]f krome cisel nacist i dve specialni hodnoty -- infinity a Nan. Ty se daji zapsat takto: "[-]inf" nebo "[-]infinity" nebo "nan". Scanf() se zastavi na prvni matching failure. V nasem pripade s "1 aa 2": precte 1, to je v poradku, precte a: ale toto nezna, takze precte acka az do mezery, pak je tam 2, ta je ok, vypise se. U "1 ii 2" ale precte 1, pak uvidi "i", tento znak je v poradku, precte dalsi, jenze tady neni 'n', coz je fail. Jelikoz rc je ted 0, provede se slurpnuti invalid inputu, ale v tomto "invalid" inputu je i nase dvojka! Pri dalsim cteni se narazi na EOF a tim padem ukoncujeme program.

Díky za odpověď. Je to správně ;).

Přidat komentář