Diskuze: Citanie int v C

C++ C a C++ Citanie int v C

Avatar
expoox
Redaktor
Avatar
expoox:

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
expoox
Redaktor
Avatar
expoox:

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
Odpovídá na expoox
Lukáš Hruda (Luckin):

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
Redaktor
Avatar
expoox:

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):

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):

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:

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
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):

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):

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:

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):

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
 
Nahoru Odpovědět 14.11.2014 7:52
Avatar
Odpovídá na vitamin
Libor Šimo (libcosenior):

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:

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):

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):

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):

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
Redaktor
Avatar
expoox:

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:

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
Posix
Člen
Avatar
Odpovídá na expoox
Posix:

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
Proč to dělat jednoduše, když to jde složitě.
Avatar
expoox
Redaktor
Avatar
Odpovídá na Posix
expoox:

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
Redaktor
Avatar
expoox:

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:

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
Redaktor
Avatar
Odpovídá na vitamin
expoox:

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.