Načtení 2D pole v C

Načtení 2D pole v C
« kdy: 18. 11. 2022, 15:53:12 »
Dobry den. Chtel bych ze souboru nacist ctvercovou matici o neznamem poctu radku/sloupcu a nasledne ji opet printnout. Nemuzu prijit na to proc to nenacita zadny cisla. Kod i input je v priloze. Predem dekuji za jakykoli feedback <3
« Poslední změna: 18. 11. 2022, 16:02:06 od Petr Krčmář »


Re:Načtení 2D pole v C
« Odpověď #1 kdy: 18. 11. 2022, 16:23:58 »
mate tam jen scanf, ten cte ze standartniho vstupu (prikazovy radek) ne ze souboru.

open, read, close nebo fopen, fread, fclose 

a6b

  • ***
  • 119
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #2 kdy: 18. 11. 2022, 16:32:43 »
jinak nejake komentare:

lepsi by bylo kod vlozit jako text, mohli bychom ho tu predelat a hned by sis to zkopiroval.

chapu, ze se ucis s polem, ale mit natvrdo maximalni pocty radku a sloupcu nastavene na 100 neni moc pekne.

array by bylo lepsi alokovat dynamicky a pri potrebe zvetseni realokovat.

mas tam for smycky pro i a j a jeste menis hodnoty i a j uvnitr smycky.

Re:Načtení 2D pole v C
« Odpověď #3 kdy: 18. 11. 2022, 16:36:49 »
mate tam jen scanf, ten cte ze standartniho vstupu (prikazovy radek) ne ze souboru.

open, read, close nebo fopen, fread, fclose

Pardon, spatne jsem se vyjadril, cisla posilam ze souboru na stdin :)

Re:Načtení 2D pole v C
« Odpověď #4 kdy: 18. 11. 2022, 16:49:11 »
jinak nejake komentare:

lepsi by bylo kod vlozit jako text, mohli bychom ho tu predelat a hned by sis to zkopiroval.

chapu, ze se ucis s polem, ale mit natvrdo maximalni pocty radku a sloupcu nastavene na 100 neni moc pekne.

array by bylo lepsi alokovat dynamicky a pri potrebe zvetseni realokovat.

mas tam for smycky pro i a j a jeste menis hodnoty i a j uvnitr smycky.
1) kod posilam v .c souboru v priloze (pouceni pro priste, diky :) )
2+3) zatim jsem si chtel udelat program pro max. matici 100x100, az to bude fungovat tak bych se chtel presunout na dyn. alokaci pro jakoukoli velikost
4) tema for loopama jsem chtel vytvorit ze pro array[0][0] ([radek=i][sloupec=j]) se zapise 1, array[0][1] -> 2 ... "\n"
array[1][0] -> 4 atd..


Re:Načtení 2D pole v C
« Odpověď #5 kdy: 18. 11. 2022, 17:06:30 »
Logická chyba na riadku 19.
Hrubá logická chyba na riadku 24.

Prečo sa Tvoj kód snaží načítať maticu, keď nie je funkčné načítanie jedného problému? T. j. narážka na to, že aký je postup riešenia problémov, t. j. či postupne z hora nadol alebo zdola nahor.

Re:Načtení 2D pole v C
« Odpověď #6 kdy: 18. 11. 2022, 17:21:20 »
Myslím, že pomocí scanf nejsi schopný poznat, kde je konec řádku, protože přeskakuje všechen whitespace.
Doporučoval bych ti si to ze začátku trochu ulehčit a dát na začátek ještě jeden řádek, kde bude napsaný rozměr matice. Až ti tohle bude fungovat, tak to potom můžeš zkusit vymyslet bez něj (ale předem upozorňuju, že to bude o dost složitější).

Re:Načtení 2D pole v C
« Odpověď #7 kdy: 18. 11. 2022, 17:28:32 »
Logická chyba na riadku 19.
Hrubá logická chyba na riadku 24.

Prečo sa Tvoj kód snaží načítať maticu, keď nie je funkčné načítanie jedného problému? T. j. narážka na to, že aký je postup riešenia problémov, t. j. či postupne z hora nadol alebo zdola nahor.
Chtel jsem si osetrit vstupy, ale ted uz chapu, ze to je asi posledni vec, kterou resit. Chapu chybu na 19.r, ale nemohl bys prosim trosku rozvinout to, v cem je chyba na 24.? Diky

Re:Načtení 2D pole v C
« Odpověď #8 kdy: 18. 11. 2022, 18:36:01 »
Moja oprava: Prečo sa Tvoj kód snaží načítať maticu, keď nie je funkčné načítanie jedného riadku?

Riadok 24., ak bolo cieľom zistiť koniec riadku, tak to nie je dobre. Dokonca, číselný vstup 32 by sa tomu rovnal.

Vstup do programu je vždy ako prúd bajtov/znakov. Funkcia scanf číta hodnoty (t.j. reťazec znakov 0 až 9, a ten konvertuje na typ int). Na načítanie riadkov služí fgets, getline a potom použiť sscanf.

Ak chceš scanf, tak tam ako oddeľovať v tomto prípade sa buď dá, že záporné číslo sa rovná zmena na nový riadok, alebo vopred sa vie počet hodnôt (počet urči pri spustení použivateľ).

Zoznám sa a používaj man stránky pre fukcie C, napr. pre . Určite si pozri sekciu Return value a pripadne príklad.

!!!! Nova extremná hrubá chyba je v riadku 16 !!! Dokonca pretečenie pamäte.

Re:Načtení 2D pole v C
« Odpověď #9 kdy: 18. 11. 2022, 19:16:54 »
Dokonca, číselný vstup 32 by sa tomu rovnal.
Drobnost: newline je ASCII 10. 32 je mezera.

Re:Načtení 2D pole v C
« Odpověď #10 kdy: 19. 11. 2022, 13:49:51 »
1. Začni tím, že se vůbec naučíš načítat hodnoty ze souboru/stdin (je to vlastně to samé, ale nebudu ti plést hlavu), tj. zadefinuj si na začátku souboru rozměry matice, ty načti a potom podle toho načítej řádky a sloupce. Až to budeš mít, vypiš si všechno zase zpátky na stdout, přesměruj do souboru a diff. Ten vstup bude vypadat cca takhle:
Kód: [Vybrat]
2 3
1 2 3
3 4 5
Až tohle budeš mít správně, jdi k bodu 2.

2. Smaž rozměry matice ze vstupu (tj. první řádek vstupu výše) a naprogramuj úplně zvlášť funkci, kterou určíš počet sloupců matice. Bude to něco ve smyslu že načteš první řádek vstupu (tj. vše až po první '\n') a z toho načteš počet platných integerů. Další postup bude, že vezmeš to, co máš z bodu 1. a budeš načítat o řádek méně (ten jsi už načetl, když jsi počítal sloupce). Navíc ještě nebudeš počítat řádky, ale budeš načítat "dokud není EOF", ptž dopředu nevíš, kolik těch řádků je. Měla by to být menší úprava kódu z bodu 1.

Až budeš mít i bod dva, udělej opět to samé co v bodu 1.: Vypiš výsledek do stdout a porovnej se vstupem (pak si můžeš udělat vstupů víc a napsat si na to bash script).

3. Až ti tohle všechno bude fungovat, můžeš vůbec začít přemýšlet o dynamické alokaci.

Na závěr se zamysli nad tím, jaké "mezní hodnoty" a nesprávné vstupy můžeš dostat. Můžeš dostat prázdný vstup, vstup větší než tvoje staticky alokované pole, matice může být tzv. "zubatá" (trochu těžší na ošetření), může obsahovat neplatné znaky atd. A zkus tyhle věci ošetřit (tj. aby například program zdechnul kontrolovaným způsobem se správnou zprávou na výstupu) nebo se aspoň zamyslet, jak to udělat.

Hinty
1. Zjisti si, jaký je rozdíl mezi scanf("%d", ...); a scanf(" %d", ...); - tj. bez mezery před formátovacím řetězcem a s mezerou ;)
2. Používej vývojové prostředí a debugger - názorně uvidíš, co se děje.
3. Automatizuj si testování.

Ink

  • *****
  • 584
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #11 kdy: 20. 11. 2022, 07:53:26 »
Otázka zní, zda vůbec používat funkci scanf() a zda by nebylo lepší udělat si vlastní konečný automat a načítat si ta čísla po znacích. Je to dost triviální.

Re:Načtení 2D pole v C
« Odpověď #12 kdy: 20. 11. 2022, 16:44:08 »
Otázka zní, zda vůbec používat funkci scanf() a zda by nebylo lepší udělat si vlastní konečný automat a načítat si ta čísla po znacích. Je to dost triviální.

To by teda nebylo lepší :) Je to dost citlivá funkce, protože načítá vstup, udělat to správně a bez chyb není vůbec triviální. A to se bavíme jen o integerech, floaty jsou úplně jiná liga. A navíc je to úplně mimo mísu pro začátečníka...

Ink

  • *****
  • 584
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #13 kdy: 20. 11. 2022, 17:10:58 »
Otázka zní, zda vůbec používat funkci scanf() a zda by nebylo lepší udělat si vlastní konečný automat a načítat si ta čísla po znacích. Je to dost triviální.

To by teda nebylo lepší :) Je to dost citlivá funkce, protože načítá vstup, udělat to správně a bez chyb není vůbec triviální. A to se bavíme jen o integerech, floaty jsou úplně jiná liga. A navíc je to úplně mimo mísu pro začátečníka...

Ano, bavíme se o integerech. Jaké hrozné problémy tam jsou? V čem je lepší používat obskurní funkce typu scanf()?.

mikrom

  • ***
  • 172
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #14 kdy: 20. 11. 2022, 17:34:38 »
@Pejtl6:
Mozes pouzit takyto postup: Textovy subor s datami otvoris s fopen() a zavries s fclose()
Subor budes citat v cykle po riadkoch za pouzitia funkcie fgets(). Pritom cisla z kazdeho riadku rozparsujes funkciou strtok() a ulozis ich do 2D pola.
Ak si s tym nebudes vediet poradit postni svoj dotaz sem https://www.tek-tips.com/threadminder.cfm?pid=205 a ja tam postnem funkcny kod