Avatar
emedla
Člen
Avatar
emedla:

Cau, nechapu proc mi nefunguje tento kod. Delam kontrolu, jestli je hodnota nactena do promenne pohyb cislo, pokud neni probehne hlaska a pozadavek na opetovne zadani hodnoty do promenne pohyb. Jenze program probehne tak, ze bezi do nekonecna a vypisuje ty hlasky.
Za 1. - nevim proc me nenecha zadat jinou hodnotu, pokud zadam pismena, tak se zacykli.
Za 2. - jak jinak to lze udelat?
Diky

Ukazka:

scanf(" %d", &pohyb);


    while((isalnum(pohyb) == 0)||(pohyb < 0))
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu-> ");
        pohyb=0;
        scanf("%d", &pohyb);

    }
 
Odpovědět 10.8.2015 14:02
Avatar
Luboš Běhounek (Satik):

jakeho typu je promenna pohyb?

Nahoru Odpovědět 10.8.2015 14:21
:)
Avatar
emedla
Člen
Avatar
Odpovídá na Luboš Běhounek (Satik)
emedla:

pohyb je typu int.
jinak jsem to jeste troche opravil:

while(((cislo=isalnum(pohyb)) == 0)||(pohyb < 0))

Ale nezabira -> scanf stale preskakuje a bezi dokola
cislo je taky typu int.
Zkousel jsem I misto isalnum() funcki isdigit(). Ale vysledek je stejny

 
Nahoru Odpovědět 10.8.2015 14:25
Avatar
kxmx
Redaktor
Avatar
kxmx:

tohle je teda solidní oprava

(cislo=isalnum(pohyb)) == 0)

nepotřebuješ náhodou testovat jestli není pohyb větší než 0?

 
Nahoru Odpovědět 10.8.2015 15:26
Avatar
emedla
Člen
Avatar
Odpovídá na kxmx
emedla:
while(((cislo=isdigit(pohyb)) == 0)||(pohyb < 0))
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu-> ");
        pohyb=0;
        scanf("%d", &pohyb);

    }

Jo, je to blbost. Zapomnel jsem to upravit. Takto by to melo byt spravne. Nicmene mi jde hlavne o to proc to v tom cyklu while ten scanf() preskakuje.
Zajimalo by me, co presne se do te pameti nacte, kdyz pri prikazu

scanf("%d", &pohyb)

napisu do teto adresy pismena. Kdybych tam nemel tu kotrolu a napsal pismena, tak to vetsinou potom vyhodi cislici v radu 5 cislic. Nechapu to, dovede mi na tohle odpovedet?
Dokonce, I kdyz tam necham prikaz

pohyb=0;

tak se to chova furt stejne. Je to ujety.

 
Nahoru Odpovědět  -1 10.8.2015 15:37
Avatar
Jozef
Člen
Avatar
Odpovídá na emedla
Jozef:

Myslím,že najlepšie pre teba bude načítať vstup do stringu a tak skontrolovať,či je zadané číslo a ak hej, skontrolovať hodnotu. Pri použití scanf, ktoré očakáva argument typu int, nemôžeš zadať nič iné ako typ int, inak to zblbne,čo si už zistil.

Nahoru Odpovědět  +1 10.8.2015 23:17
I'm not afraid to die on a treadmill
Avatar
Odpovídá na Jozef
Libor Šimo (libcosenior):
#include<stdio.h>

int main(void)
{
    int pohyb;

    printf("Zadajte sumu: ");
    scanf(" %d", &pohyb);
    while((pohyb == 0)||(pohyb < 0))
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu: ");
        pohyb=0;
        scanf("%d", &pohyb);
    }

    return 0;
}
Nahoru Odpovědět 11.8.2015 8:09
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Libor Šimo (libcosenior)
Libor Šimo (libcosenior):

Teraz som si všimol, toto stačí.
while(pohyb <= 0)

Nahoru Odpovědět 11.8.2015 8:44
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Ináč makrá z knižnice ctype.h sa týkajú jednotlivých znakov, nie viacciferných čísiel alebo stringov!

Nahoru Odpovědět 11.8.2015 8:46
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Libor Šimo (libcosenior):

Napísal si:
"Pri použití scanf, ktoré očakáva argument typu int, nemôžeš zadať nič iné ako typ int, inak to zblbne,čo si už zistil."

Nesúhlasím, vyskúšaj si tento programík:

#include <stdio.h>

int main(void)
{
    int i, pohyb;

    for (i = 0; i < 5; i++) {
        printf("Zadajte slovo: ");
        scanf(" %d", &pohyb);
        printf("%d\n", pohyb);
        fflush(stdin); /* odstráni enter */
    }

    return 0;
}
Nahoru Odpovědět  +1 11.8.2015 9:02
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
emedla
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
emedla:

Bohuzel nestacilo. Opet to porad bezelo dokola.

 
Nahoru Odpovědět 11.8.2015 9:14
Avatar
emedla
Člen
Avatar
emedla:

Spravnym resenim je jak rikal Jozef toto:
Alespon teda pro me :).

scanf("%s", r_pohyb);

    while(((pohyb=atoi(r_pohyb))<=0))
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu-> ");
        //pohyb=0;
        scanf("%s", r_pohyb);

    }

Vse funguje jak ma.
Funkce atoi() vraci nulu, pokud se nejedna o retezec slozeny z cisel

 
Nahoru Odpovědět 11.8.2015 9:20
Avatar
emedla
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
emedla:

Aha jo.
Tak tohle je co mi tam chybelo:

fflush(stdin);

Kdyz to zakomentuju, tak to bezi 5x dokola zase samo. Je to tim, ze ten enter tam furt visi?
Jak to tam presne funguje?
Diky

 
Nahoru Odpovědět 11.8.2015 9:29
Avatar
patrik.valkovic
Šéfredaktor
Avatar
Odpovídá na emedla
patrik.valkovic:

Tyto knihovny čtou zpravidla do konce řádku (tedy do znaku '\n'). Jestliže ti visí enter na konci řádku, tak to pro funkci vypadá, jako by jsi nic nezadal (jako kdyby jsi hned odentroval). Protože ale ve frontě nějaký znak je, tak by program neměl čekat na vstup od uživatele ale pokračovat s tím, co přečetl (v tomto případě nic - "\0"). Snad to stačí takhle.

Nahoru Odpovědět 11.8.2015 9:39
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
emedla
Člen
Avatar
 
Nahoru Odpovědět 11.8.2015 9:56
Avatar
Odpovídá na emedla
Libor Šimo (libcosenior):

"Spravnym resenim je jak rikal Jozef toto:
Alespon teda pro me."

Skús zadať

1235k

a uvidíš, že to nie je dobre!

Nahoru Odpovědět 11.8.2015 10:04
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Jozef
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
Jozef:

Pri neočakávanom vstupe scanf() síce nevyhodí chybu, ale dôjde k neočakávanému správaniu. Funkcia fflush(stdin) iba vyčistí buffer od zostávajúceho znaku, ale to neznamená, že scanf() funguje. Vyskúšaj túto úpravu tvojho programu, zadaj si tam číslo alebo slovo a uvidíš rozdiel:

#include<stdio.h>

int main(void)
{
    int i, pohyb;

    for (i = 0; i < 5; i++) {
        printf("Zadajte slovo: ");
        int ret = scanf(" %d", &pohyb);
        printf("%d\n",ret);  // vypíše počet správne prevedených a zapísaných znakov
        printf("%d\n", pohyb);
        fflush(stdin); /* odstráni enter */
    }

    return 0;
}
Nahoru Odpovědět 11.8.2015 10:13
I'm not afraid to die on a treadmill
Avatar
Jozef
Člen
Avatar
Odpovídá na emedla
Jozef:

Vyskúšaj toto:

#include<stdio.h>
#include <stdlib.h>
#include<string.h>

int main(void)
{
    char s_pohyb[100];
    char *chybne;
    scanf("%s", s_pohyb);
    int pohyb;
    while((pohyb = strtol(s_pohyb, &chybne, 10) <= 0)||(strlen(chybne)))
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu-> ");
        scanf("%s", &s_pohyb);

    }
    return 0;
}

Ak zadáš číslo a je menšie ako 0 alebo zadáš niečo iné ako číslo, alebo zadáš číslo nasledované znakom(napr. spomínané "1235k") tak to vyhodí do while cyklu. Ak ale chceš, aby ti po zadaní "1235k" prečítalo vstup iba ako číslo 1235, tak vyhoď z podmienky

||(strlen(chybne))

Potom ti prečíta všetky číslice pred chybou, teda iným znakom- napr. po zadaní 12a5 bude v premennej pohyb uložené číslo 12; ale po zadaní a55 sa dostaneš do while cyklu.

Nahoru Odpovědět 11.8.2015 10:28
I'm not afraid to die on a treadmill
Avatar
Odpovídá na Jozef
Libor Šimo (libcosenior):

Máš pravdu, ale platí to iba na celé čísla a ak som správne pochopil prvý príspevok, majú sa zadávať finančné čiastky (pohyb na účte).
Neviem, či na to existuje funkcia, ja by som to riešil asi takto:

#include <stdio.h>
#include <stdlib.h>

/** Funkcia skontroluje ci je retazec cislo
* @param pointer na retazec
* @return 1 alebo 0 (pravda 1, nepravda 0)
*/
int je_cislo(char *cislo)
{
    int i = 0, bodka = 0, je = 1;

    while (cislo[i]) {
        if ((cislo[i] < '0' || cislo[i] > '9') && cislo[i] != '.') { /* znaky su ine ako cislice a bodka, cislo je neplatne */
            je = 0;
        }
        if (cislo[i] == '.') /* spocitanie bodiek */
            bodka++;
        i++;
    }
    if (bodka > 1) /* ak je viac bodiek ako jedna, cislo je neplatne */
        je = 0;

    return je;
}

int main(void)
{
    char r_pohyb[50];

    scanf("%s", r_pohyb);
    while (!(je_cislo(r_pohyb)) || atof(r_pohyb) <= 0.0)
    {
        printf("Pohyb na ucte lze vyjadrit pouze cislem vetsim jak 0\n");
        printf("Prosim zadejte znovu pohyb na uctu-> ");
        scanf("%s", r_pohyb);
    }

    return 0;
}
Nahoru Odpovědět 11.8.2015 11:04
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Jozef
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
Jozef:

Riešil som to pre jeho zadanie a v ňom bola premenná pohyb typu int. Ak by išlo o premennú typu float, existuje funkcia strtof (http://www.cplusplus.com/…dlib/strtof/) a ak by chcel použiť double tak funkcia strtod (http://www.cplusplus.com/…dlib/strtod/).

Nahoru Odpovědět  +1 11.8.2015 11:20
I'm not afraid to die on a treadmill
Avatar
Jozef
Člen
Avatar
Odpovídá na Jozef
Jozef:

Teda jedine by bola treba veľmi drobná úprava kódu, ktorý som ukázal:

float pohyb;                //double pohyb
while((pohyb = strtof(s_pohyb, &chybne) <= 0.0)||(strlen(chybne)))   //pohyb = strtod(..ostatné nezmenené
Nahoru Odpovědět  -1 11.8.2015 11:24
I'm not afraid to die on a treadmill
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 21 zpráv z 21.