Apua! Ristinollatekoälyni ei toimi! Aluksi toteutin tiedostosta lukemisen käyttämällä taulukkoa koordinaateille ja lukemisen jälkeen käymällä taulukon läpi lopusta alkuun ja merkitsemällä ruudukkoon koordinaattien kohdalle ristit ja nollat. Sitten tajusin että on paljon järkevämpää tehdä merkinnät samalla kun lukee tiedostosta, jolloin ei tarvita taulukkoa koordinaateille. Mutta nyt tekoäly suorittaa laittoman toiminnon kun sen ajaa.
Tässä vielä vähän koodia selvennykseksi:
if ((file=fopen("IQ200.luk","r"))) { fscanf(file,"%d",&ruudukonkoko); while (1) { if (fscanf(file,"%d %d",&x,&y)==EOF) { break; } x--; y--; ruudukko[x][y]=1; }
Muuttuja "ruudukko" ei ole alustettu oikein. Sen pitäisi olla ruudukko[ruudukonkoko][ruudukonkoko]. Paitsi, jos se on aina 50. Muuta en keksinyt, ainakaan heti.
Se on ruudukko[50][50], joten ei se siitä voi johtua. Ensin tuli mieleen, että ohjelma yrittäisi lukea tiedoston "ulkopuolelta", mutta eihän se siitäkään voi johtua(?)
C-kielistä tuskin mitään enää muistan, mutta pitäisikö tuo rivinvaihtomerkkikin joskus fskannata pois? (Ettei sitä tulkita seuraavassa luvussa uudeksi x-koordinaatiksi.)
(Pidätän oikeuden poistaa tämä kommentti, jos tämä on ihan hölmö.) :)
lainaus:
if (fscanf(file,"%d %d",&x,&y)==EOF)
Minun mielestä tuo ei ole oikein. Eikös tuo funktio, kuten monet
muutkin, palauta vain 0, jos epäonnistuu, tai 1, jos onnistuu?
Eli tässä tapauksessa koodin toimivuus riippuu siitä, mikä arvo EOF-muuttujalla on. Senhän pitäisi loogisesti olla -1, eli True.
Eivätkös scanf-funktiot palauta onnistuessaan luvun, joka vastaa tallennettavien muuttujien lukumäärää? Epäonnistuessa se palauttaa nollan tai tässä tapauksessa EOF (tarkistin referencestä).
Eräs tapa etsiä ongelmaa olisi debug tai sitten vain tulostaa jokaisen muuttujan arvon, jolloin näkee sekoamiskohdan.
Vai niin... Laitoin ohjelman tulostamaan .luk-tiedoston sisällön näytölle, ja tällaista tulostui:
65535, 2
65535, 2
65535, 1
65535, 2
65535, 0
65535, 1
65535, 3
65535, 0
65535, 65535
65535, 3
65535, 0
65535, 1
65535, 2
65535, 3
65535, 4
65535, 5
65535, 65535
65535, 4
65535, 65535
65535, 5
65535, 0
Jotain tuossa kyllä näyttää olevan väärin.. Ohjelma siis vähentää jokaisesta arvosta yhden, joten onko 65536 mahdollisesti jokin erikoisluku (maksimi-integer?) Koitin myös laittaa EOFin tilalle nollan ja samoin kävi.
Edit: Ai niin, x ja y ovat muotoa short.
Edit2: Nyt tässä on jotain mätää. Laitoin ohjelman kirjoittamaan koordinaatit käänteisessä järjestyksessä (y,x eikä x,y), ja se tulosti täsmälleen samat luvut!!
nakkikorva kirjoitti:
Jotain tuossa kyllä näyttää olevan väärin.. Ohjelma siis vähentää jokaisesta arvosta yhden, joten onko 65536 mahdollisesti jokin erikoisluku (maksimi-integer?)
Kyllä, se on maksimi-integer, jonka arvo voi olla vain positiivinen (tai nolla). Noin voi käydä, jos vaikka vahingossa yrität antaa sellaiselle muuttujalle arvon -1, jolloin muuttujan arvo tavallaan "kiertää ympäri" ja alkaa taas 65535:sta. Samoin, jos ylität luvun 65535, niin luku alkaa taas nollasta. Eikös tuollainen vain-posiivinen-integer saada kun pistetään eteen unsigned?
Testasin tuota, vaihdoin shortit inteiksi, toimii ihan loistavasti. En tiedä, miksi ei toimi shortteina (sitä testasin ensin). Tässä koodi:
#include <stdio.h> int main(int argc, char *argv[]) { int x, y; int ruudukonkoko; FILE *file; if ((file=fopen("testi.luk","r"))) { fscanf(file,"%d",&ruudukonkoko); printf("%d\n", ruudukonkoko); while (1) { if (fscanf(file,"%d %d",&x,&y)==EOF) { break; } x--; y--; printf("%d %d\n", x, y); } } return 0; }
Hienosti sisennetty, kuten lainaamalla tekstiäsi näkee, mutta siitä ei ole mitään hyötyä tässä, ellet käytä ohjeissa selitettäviä kooditageja:
#include <stdio.h> int main(int argc, char *argv[]) { int x, y; int ruudukonkoko; FILE *file; if ((file=fopen("testi.luk","r"))) { fscanf(file,"%d",&ruudukonkoko); printf("%d\n", ruudukonkoko); while (1) { if (fscanf(file,"%d %d",&x,&y)==EOF) { break; } x--; y--; printf("%d %d\n", x, y); } } return 0; }
Edit: Mihin kummaan muuten on kadonnut koodin sininen väri? Nythän tuo on kokonaan mustaa.
Hyvinhän sininen loistaa. Ainoa mikä on musta vaikka sen pitäisi olla sininen on break...
Dual kirjoitti:
Hyvinhän sininen loistaa. Ainoa mikä on musta vaikka sen pitäisi olla sininen on break...
Sanopa, mitä näet tuossa koodissa sinisellä? Minä nimittäin näen siinä vain mustaa tekstiä.
hunajavohveli kirjoitti:
Dual kirjoitti:
Hyvinhän sininen loistaa. Ainoa mikä on musta vaikka sen pitäisi olla sininen on break...
Sanopa, mitä näet tuossa koodissa sinisellä? Minä nimittäin näen siinä vain mustaa tekstiä.
Kyllä siinä on sinistä. Ootko tullu värisokeeks :D
<span style="color: blue;">int</span> main(<span style="color: blue;">int</span> argc, <span style="color: blue;">char</span> *argv[])
No eipä näy minulla sinisestä jälkekään. Käytän Operaa, että olisikohan sillä mitään merkitystä? Kyllä koodivinkeissä ainakin väritys näkyy.
Sit sun vaan pitää kattoa onko siellä lähdekoodissa noita tageja vai johtuuko se Operasta. Jos johtuu operasta niin sit pitää vaihtaa Firefoxiin!
Alkuperäiseen ongelmaan viitaten, %d tarkoittaa 32-bittistä integeriä, mutta annat scanf:lle parametreinä vain 16-bittisiä integerejä (short), siksi tuo sekoaa.. Jos haluaa lukea shorttiin, niin %d pitäisi olla esimerkiksi %hd.
Nyt toimii! Kiitos kaikille
Aihe on jo aika vanha, joten et voi enää vastata siihen.