IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: Citanie int v C

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
expoox
Tvůrce
Avatar
expoox:13.11.2014 12:36

Zdravim, potrebujem nacitat stdin vo formate: %d %d %d .... teda cele cisla oddelene medzerou (presny pocet nieje zadany a vypis konci s EOF) a moj problem ze vobec neviem ako na to, robil som nieco v zmysle:

int i=0;

while (scanf("%d ",&pole[i])!=-1)
  i++;

ale nefunguje to velmi, budem vdacny za akukolvek radu

 
Odpovědět
13.11.2014 12:36
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na expoox
Lukáš Hruda:13.11.2014 12:47

Proč tam máš -1 ?

 
Nahoru Odpovědět
13.11.2014 12:47
Avatar
expoox
Tvůrce
Avatar
expoox:13.11.2014 12:49

no pokial mi je zname tak ak scanf narazi na EOF tak by mal vratit -1, ale to je jedno, skusal som tam aj miesto nej dat EOF a taky isty vysledok

 
Nahoru Odpovědět
13.11.2014 12:49
Avatar
Lukáš Hruda
Tvůrce
Avatar
Odpovídá na expoox
Lukáš Hruda:13.11.2014 15:48

EOF je makro indikující konec souboru, ty ale načítáš z konzole a ta je považována ze nekonečný souboru tedy na EOF nikdy nenarazíš.

 
Nahoru Odpovědět
13.11.2014 15:48
Avatar
expoox
Tvůrce
Avatar
expoox:13.11.2014 17:28

nenapadlo ma davat mu na vstup subor, vyskusam ...

 
Nahoru Odpovědět
13.11.2014 17:28
Avatar
Odpovídá na expoox
Libor Šimo (libcosenior):13.11.2014 17:30

Presne tak, stdin a efektívne sa používajú pri práci so súbormi.

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

eof, nie efektívne

Nahoru Odpovědět
13.11.2014 17:30
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
vitamin
Člen
Avatar
Odpovídá na expoox
vitamin:13.11.2014 17:45

scanf vracia pocet uspesne nacitanych dat alebo EOF ak nastala chyba hned na aciatku. (http://en.cppreference.com/…/io/c/fscanf).
podmienk by mala vyzerat takto:

(scanf("%d ",pole+i) == 1)
Editováno 13.11.2014 17:45
 
Nahoru Odpovědět
13.11.2014 17:45
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):13.11.2014 18:03

aj si to otestoval?

Nahoru Odpovědět
13.11.2014 18:03
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):13.11.2014 20:37

poprosím ťa, daj sem celý kód

Nahoru Odpovědět
13.11.2014 20:37
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):13.11.2014 20:39

zdá sa, že tvoje riešenie je v c++, alebo sa mýlim?

Nahoru Odpovědět
13.11.2014 20:39
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
vitamin
Člen
Avatar
Odpovídá na Libor Šimo (libcosenior)
vitamin:13.11.2014 20:42

V tomto by nemal byt rozdiel medzi c a c++.

int i;
assert(scanf("%d%d", &i, &i) == 2);
 
Nahoru Odpovědět
13.11.2014 20:42
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):14.11.2014 7:34

To čo si napísal predtým, nefunguje.

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

int main()
{
    int i=0, pole[50];

    while (scanf("%d", pole + i) == 1)
        i++;
    printf("KONIEC!\n");

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

Co ti na tom nefunguje?

 
Nahoru Odpovědět
14.11.2014 7:52
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):14.11.2014 10:55

V prvej správe je zadanie: vo formate: %d %d %d .... teda cele cisla oddelene medzerou (presny pocet nieje zadany a vypis konci s EOF)

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

Ved zadaj celé čísla oddelene medzerami a ukonči ich s EOF a bude to fungovať.

 
Nahoru Odpovědět
14.11.2014 12:33
Avatar
Libor Šimo (libcosenior):14.11.2014 13:00

Poraď mi ako zadám EOF.

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

Sorry, už som to skúsil, nevedel som, že je niečo také možné.

Nahoru Odpovědět
14.11.2014 13:02
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):14.11.2014 13:21

Konečne tomu rozumiem. Asi my to dnes veľmi nemyslí.
Podmienka: (scanf("%d ", pole+i) == 1)
je splnená, ak je zadaný výraz TRUE a nesplnená, keď je FALSE.
Teda vlastne pod EOF sa myslí, čokoľvek iné ako int.

Nahoru Odpovědět
14.11.2014 13:21
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
expoox
Tvůrce
Avatar
expoox:15.11.2014 13:59

Tak som sa k tomu konecne dostal a zistil som ze to stale neviem zistit ... prikladam kod /* teraz som pre zmenu prisiel na to ze neviem pracovat s malloc() */

int *cisla;
    int k=1;

    cisla=(int*)malloc(k*sizeof(int));

    while (1)
    {

        switch (scanf("%d",&cisla[k-1]))
        {
            case 1:
            {
                k++;
                cisla=(int*)malloc(k*sizeof(int));
            }
                break;
            case EOF: goto out;
            default:
            {
                printf("Nespravny vstup.\n");
                return 0;
            }
        }
    }
    out:
 
Nahoru Odpovědět
15.11.2014 13:59
Avatar
vitamin
Člen
Avatar
Odpovídá na expoox
vitamin:15.11.2014 14:46

Mal by si najpr prkeopyrovat prvky so stareho pola do noveho(napr memmove/memspy) a az potom prepisat pointer 'cisla'. Nasledne by si mal stare pole zmazat pomocou free. Jednoduhsia verzia je pomocou realloc co za teba prekopyruje a zmaze stare pole (niekedy sa podari rozsirit pamet bez mazania starej tak to bude aj rychlejsie). Ten cyklus by sa dal napisat aj bez goto ktoremu je dobre sa vyhybat ak je to mozne (niekedy sa hodi ale toto nie je ten pripad).
edit: allokacia je dost pomala, preto je lepsie alokovat po vecsich blokoch.

Editováno 15.11.2014 14:48
 
Nahoru Odpovědět
15.11.2014 14:46
Avatar
Odpovídá na expoox
Neaktivní uživatel:15.11.2014 15:02

No je tam spusta divného kódu.
Ten druhý malloc ve switchi vytvoří vždy nové pole a k tomu starému se už nikdy nedostaneš, protože přepíšeš starou adresu. Takže ve výsledku máš N polí pro N zadaných čísel a v každém poli je zapsané jen číslo pro poslední prvek. Funkci, kterou hledáš pro zvětšování pole je realloc.
Taky není nejlepší realokovat pro přidání nového prvku, ale vždy alokovat místo pro víc položek pole a teprve až dojde místo, tak třeba zdvojnásobit velikost. Tím se ale asi zatím nemusíš zabývat, když ještě neumíš pořádně ani základy.
A ten příkaz goto nepoužívej u takového případu, kdy je na první pohled jasné, že není vůbec potřeba.

Jestli jsem teda pochopil, co chceš, tak by to mohlo vypadat tak nějak:

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

int main(int argc, char** argv)
{
    int k = 1;
    int *cisla = (int*)malloc(k*sizeof(int));

    while (scanf("%d", cisla + (k - 1)) != EOF)
    {
        int cislo = cisla[k - 1];
        if (cislo == 1)
        {
            k++;
            cisla = (int*)realloc(cisla, k * sizeof(int));
        }
        else
        {
            printf("Nespravny vstup.\n");
            return 0;
        }
    }

    return 0;
}
Nahoru Odpovědět
15.11.2014 15:02
Neaktivní uživatelský účet
Avatar
expoox
Tvůrce
Avatar
Odpovídá na Neaktivní uživatel
expoox:15.11.2014 15:09

to je to co som potreboval, tomu goto som sa chcel aj ja vyhnut ale nevedel som ako dva krat breaknut vo switchy a nenapadlo ma ho uplne vynechat,
dakujem pekne za pomoc :)

 
Nahoru Odpovědět
15.11.2014 15:09
Avatar
expoox
Tvůrce
Avatar
expoox:16.11.2014 11:19

Len tak pre zujimavost ten switch som si tam nechal a goto vynechal takto

eofile=1;

while (eofile)
    {
        switch (scanf("%d",&cisla[pocet-1]))
        {
            case 1:
            {
                .....
                break;
            }
            case EOF:
            {
                eofile=0;
                ....
                break;
            }
            default:
            {
                ....
            }
        }
    }
 
Nahoru Odpovědět
16.11.2014 11:19
Avatar
vitamin
Člen
Avatar
vitamin:16.11.2014 11:35

Da sa to aj bez pomocnej premennej:

while (1)
    {
        switch (scanf("%d",&cisla[pocet-1]))
        {
            case 1:
            {
                .....
                continue;
            }
            case EOF:
            {
                ....
                break;
            }
            default:
            {
                ....
            }
        }
        break;
    }

Lepsie riesenie je aj tak to od Posix.

Editováno 16.11.2014 11:36
 
Nahoru Odpovědět
16.11.2014 11:35
Avatar
expoox
Tvůrce
Avatar
Odpovídá na vitamin
expoox:16.11.2014 11:54

toto ti nebude fungovat, tvoj cyklus sa ukonci po prvom prechode
// ok bude nevsimol som si to continue :D

Editováno 16.11.2014 11:55
 
Nahoru Odpovědět
16.11.2014 11:54
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 27 zpráv z 27.