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

Od Petr Zemek, 2010-11-16

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.

Obsah tohoto pole je soukromý a nebude veřejně zobrazen.

Filtrované HTML (využíváno)

  • Povolené HTML značky: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <table>
  • Zvýraznění syntaxe kódu lze povolit přes následující značky: <code>, <blockcode>, <bash>, <c>, <cpp>, <haskell>, <html>, <java>, <javascript>, <latex>, <perl>, <php>, <python>, <ruby>, <rust>, <sql>, <text>, <vim>, <xml>, <yaml>.
  • Řádky a odstavce se zalomí automaticky.
  • Webové a e-mailové adresy jsou automaticky převedeny na odkazy.
CAPTCHA
2 + 6 =
Vyřešte tento jednoduchý matematický příklad a vložte výsledek. Např. pro 1+3 vložte 4.
Nějak se mi tady rozmohl spam, takže poprosím o ověření.

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.