Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ohjelma lukee tiedoston virheellisesti

Kray [24.03.2007 11:27:06]

#

On tälläinen ongelma, kun tiedosto kirjoittuu, mutta se lukeutuu väärin:

void write()
{    FILE *fpt;
     int a,b;
     fpt = fopen("data/maps/map1.map", "w");

     for(a=1; a<20;)
     {        for(b=1; b<20;)
              {        fprintf(fpt,"%d",alue_maa[b][a]);
                    ++b;
              }
              fprintf(fpt,"\n");
     ++a;
     }
     fclose(fpt);



}
void read()
{    FILE *fpt;
     int a,b,c;
     fpt = fopen("data/maps/map1.map", "r");

     for(b=1; b<18;)
     {        for(a=1; a<18;)
              {        c=getc(fpt);

                       if(c==49){alue_maa[b][a]=1;}
                       if(c==50){alue_maa[b][a]=2;}

                       ++a;
              }
            ++b;
     }
     fclose(fpt);



}

Kun määrään for lauseella tuon alue_maa:n jokaisen kohdan vaikka arvoksi 1, niin kun kutsun tuon write funktion, se kirjoittuu ykkösinä, ja se on oikein. mutta kun sen sitten lukee tuolla read:lla, se sotkee mukaan nollia, ja sekoittaa ne sekaisin keskenään. Mikä on vika?

TsaTsaTsaa [24.03.2007 11:34:41]

#

Miksi kirjoituksessa ja luvussa on for-silmukoissa eri lopetusehdot? Ja onko tarkoituksellista, että a ja b kasvaa aina kahdella joka kierroksella? Jos ei, niin ota ++a:t ja ++b:t pois.

Enkä kyllä ymmärtänyt, mitä tuossa tiedostoon kirjoitetaan ja miksi sieltä pitäisi tulla pihalle 49 tai 50, mutta se on varmaan omaa tyhmyyttäni.

EDIT: Enpä äsken huomannutkaan, mutta miksei sulla noi ++a ja ++b ole siellä missä pitää, eli for(a=0 ; a<20 ; ++a)?

tgunner [24.03.2007 12:07:24]

#

Toi luuppi kannattaa alkaa nollasta, koska sulla jää taulukoittes nolla-alkio täyttämättä. Sit kantsii kummassakin silmukassa tehdä samanlainen luuppailu, et saat kaiken tiedon käyttöön. Ei tossa sitten muuta vikaa ainakaan koodia katsoessa huomannut (paitsi TsaTsaTsaan mainitsemat). Kai sinulla on sentään tuo alue_maa -muuttuja käytössä noille funktioille. :D

Legu [24.03.2007 12:46:21]

#

No tässä on nyt tämmönen:

#include <stdio.h>

// Mitä tyyppiä mapin alkiot ovat? (tässätapauksessa arvot väliltä 0 - 255)
typedef unsigned char map;

int saveMap(const char* filename, map * mapPtr, int mapX, int mapY)
{
 	 int i, a;
 	 FILE * filePtr;
 	 filePtr = fopen(filename, "w");

 	 if (!filePtr)
 	 	return 0;

 	 for (i = 0; i < mapY; i++) {
	 	 for (a = 0; a < mapX; a++) {
		 	 fprintf(filePtr, "%d ", mapPtr[i * mapX + a]);
		 }
		 fprintf(filePtr, "\n");
     }

     fclose(filePtr);

     return 1;
}

int loadMap(const char* filename, map * mapPtr, int mapX, int mapY)
{
 	 int i, a;
 	 FILE * filePtr;
 	 filePtr = fopen(filename, "r");

 	 if (!filePtr)
 	 	return 0;

 	 for (i = 0; i < mapY; i++) {
	 	 for (a = 0; a < mapX; a++) {
		 	 fscanf(filePtr, "%d", &mapPtr[i * mapX + a]);
		 }
     }

     fclose(filePtr);

     return 1;
}

int main(int argc, char *argv[])
{
    // mapin tiedot, voisi käyttää myös kaksiulotteista taulukkoa.
    map mappi[20] = {123, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    // tallennetaan mappi:n tiedot -> testi.txt, leveys 10, korkeus 2
    saveMap("testi.txt", (map*)&mappi, 10, 2);
    map samaMap[20];
    // ladataan testi.txt:n tiedot -> samaMap, leveys 10, korkeus 2
    loadMap("testi.txt", (map*)&samaMap, 10, 2);
    // tallennetaan samaMap:n tiedot -> loaded.txt, leveys 10, korkeus 2
    saveMap("loaded.txt", (map*)&samaMap, 10, 2);

    // virheenkäsittelyesimerkki, ei tee mitään
    if (!loadMap("ei_ole.map", (map*)&mappi, 10, 2))
        printf("Lataus epaonnistui!\n");
    else
  	printf("Onnistui!\n");

  return 0;
}

Toimii siis asciina. loadMap():n kannattaisi lukea mapin leveys ja korkeus tiedostosta, mutta sitten olisi pitänyt varailla muistia dynaamisesti, niin ajattelin nyt pitää tämän yksinkertaisena. Formaatti on: mappi[0] vasen yläkulma, mappi[1] yksi oikealle ... mappi[koko-1] on oikea alakulma.

Tuloksena pitäisi olla kaksi tiedostoa (testi.txt, loaded.txt), joissa molemmissa näin:

123 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Niin ja ylimääräiset välilyönnit ja rivinvaihdon voisi ottaa pois.

Jos binaryna haluat niin katso funktiot fread() ja fwrite().

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta