Avatar
Martin Kobelka:

Dobrý den

Omlouvám se že dnes už obtěžuji po druhé. Mám takový dotaz na jeden příklad, kterými nejde do hlavy. Tento program jednoduše převádí měnu v daném kurzu.

#include <stdio.h>

int main(void)
{
    int eur;
    while(1) {
        printf("zadejte kolik máte eur: ");

        scanf("%d", &eur);

        printf("Je to %f korun\n", eur * 26.5);
    }
    return 0;
}

V případě kdy zadám číslo, tak program funguje. V případě kdy zadám znak tak program začne do nekonečna vypisovat to samé a další vstup už po mě nepožaduje. Kde je chyba? Jak to ošetřit. Přemýšlíme nad tim ve dvou a ani jeden nevíme. Děkuji za odpověď :)

 
Odpovědět 25. září 21:53
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na Martin Kobelka
Filip Šohajek:

scanf v tomto případě nedovede naparsovat vstup, proto nechá stdin neflushnutý, čili v dalši iteraci mu příjde ten samý vstup. Řešením by bylo testovat vrácenou hodnotu na 0 a případně flushnout stdin pomocí funkce fflush.

Editováno 25. září 22:04
 
Nahoru Odpovědět 25. září 22:02
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Martin Kobelka
Jan Vargovský:
if(scanf("%d", &eur) == 1)
{
        printf("Je to %f korun\n", eur * 26.5);
}
else
{
        printf("Neplatny znak\n");
        while((getchar())!='\n');
}

Jde o to, že máš nějaký buffer v pozadí a z něj bereš data. Jestliže máš v bufferu třeba "x123", tak se pořád snaží najít číslo, ale to tam není. Takže ti jen vrátí, že tam číslo není, ale to 'x' tam pořád zůstane.

 
Nahoru Odpovědět 25. září 22:04
Avatar
Odpovídá na Martin Kobelka
Neaktivní uživatel:
/* Prevod EUR/CZK */

#define _CRT_SECURE_NO_WARNINGS

#include <conio.h> // _getch()
#include <ctype.h> // isdigit()
#include <stdio.h> // printf(), putchar()
#include <stdlib.h> // atof()

int main(int argc, char *argv[]){

        char eur[11] = ""; // castka v EUR
        unsigned char c; // cislice tvorici castku v EUR
        int done = 0; // status hlavni smycky programu (0 - beh, 1 - konec)
        int pos = 0; // pozice v retezci castky v EUR
        const double kurz = 26.5; // kurz EUR/CZK

        printf("Prevod EUR/CZK\n\n");
        while (!done) {
                printf("Zadejte kolik mate EUR: ");
                do {
                        c = _getch();
                        if (isdigit(c)) {
                                if (pos < 10) {
                                        putchar(c);
                                        eur[pos] = c;
                                        pos++;
                                }
                        }
                } while ((c != '\r')||(!pos));
                eur[pos] = '\0';
                printf("\n%s EUR = %.2f CZK\n\n", eur, atof(eur) * kurz);
                printf("Chcete pokracovat\? [a/n]: ");
                do {
                        c = _getch();
                } while ((c != 'a') && (c != 'n'));
                putchar(c);
                if (c == 'a') pos = 0;
                else done = 1;
                printf("\n\n");
        }
        return 0;
}

Ono použití funkce scanf() je samo o sobě dost nešťastné řešení. Programátor má velmi malou kontrolu nad tím jak ošetřit chyby na vstupu. Funkce je v knížkách uváděna zejména pro svoji jednoduchost. Každý program je ale jiný, což si vyžaduje individuální přístup k danému řešení. Problem se dá řešit mnoha způsoby. Funkce scanf() nabízí možnost určit sadu zpracovávaných znaků, dokonce umožňuje omezit maximální délku řetězce přiřazeného do jejího argumentu a pak aplikovat funkce ze standardní knihovny jazyka C. Nebo využít vhodnější funkci pro práci s řetězci funkci gets(). Ale ani ona sama bez použití dalších funkcí řešení nenabízí. Není ale nic snazšího než si načtení čísla s kontrolou ošetření chyb naprogramovat sám. viz kód.

PS: Ještě jedna věc, pozor na českou diakritiku v kódu. Bez určení znakové sady se nebudou znaky vypisovat správně.

Nahoru Odpovědět 26. září 15:05
Neaktivní uživatelský účet
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.