Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ongelma yli 8 bitin lukujen tallennuksessa

Sivun loppuun

DumTom [18.12.2010 09:27:10]

#

Vasta olen dos-maailmasta hyökännyt SDL:än kimppuun.
Nyt olen kolmisen tuntia miettinyt ratkaisua.
Aiemmin latasin ja tallensin yli 255 luvut näin:

//LATAUS:
FILE *C;
C=fopen(nimi,"rb");
if (C==NULL) return 1;
short l=getc(C),t=getc(C);
short kpl=l*255+t;
BAR[t].SetItemKpl(kpl);

//TALLENNUS
FILE *C;
C=fopen(nimi,"wb");
short kpl=BAR[t].GetItemKpl();;
short l=kpl/255,t=kpl%255;
putc(l,C);putc(t,C);

Välillä homma jopa toimii noin mutta v******a sen verran jo että pikaista apua kaikenkokoisten lukujen helppoon tallennukseen...... :) (:

Teuro [18.12.2010 09:29:24]

#

eikös perus int ole ihan 32-bittinen, joten ei pitäisi olla ongelmia tilan kanssa.

DumTom [18.12.2010 09:30:45]

#

putc ja getc eivät kykene yli 255 lukuihin.....

Teuro [18.12.2010 09:39:05]

#

Onko pakko käyttää juuri noita funktioita? Tai siis mikä pakottaa kirjoittamaan ja lukeamaan noin hankalasti?

DumTom [18.12.2010 09:43:35]

#

siihen apua pyydänkin eli miten mätkin suuren taulukon kaikki luvut helpolla tavalla tiedostoon....noi oli vaan esimerkkejä entisestä jotka jostain syystä välillä toimivat ja välillä eivät.....eli varmaan niitä streameja

Teuro [18.12.2010 09:52:51]

#

Joo siis jos voit käyttää c++:a, niin asiat takuulla helpottuvat, kun lukeminen ja kirjoittaminen on tehty melko helpoksi.

#include <iostream>
#include <fstream>

int main() {
	int iso_taulukko[300];

	std::ofstream ulos("nimi.txt", std::ios::out);

	for (int i = 0; i < 300; ++i) {
		ulos << iso_taulukko[i] << std::endl;
	}

    return EXIT_SUCCESS;
}

DumTom [18.12.2010 10:31:40]

#

Sain tallennuksen toimimaan mutta kuinka LUEN?

Tallensin näin ja toimii,tiedosto syntyy

int NewSaveBarrelFile(char nimi[])
{
std::ofstream ulos(nimi,std::ios::out);
for (int t=0;t<2500;t++)
    {
    ulos << BAR[t].GetOn() << std::endl;
    ulos << BAR[t].GetType() << std::endl;
    ulos << BAR[t].GetOpened() << std::endl;
    ulos << BAR[t].GetKuva() << std::endl;
    ulos << BAR[t].GetX() << std::endl;
    ulos << BAR[t].GetY() << std::endl;
    ulos << BAR[t].GetOX() << std::endl;
    ulos << BAR[t].GetOY() << std::endl;
    ulos << BAR[t].GetKerros() << std::endl;
    ulos << BAR[t].GetItem() << std::endl;
    ulos << BAR[t].varattu1 << std::endl;
    ulos << BAR[t].varattu2 << std::endl;
    ulos << BAR[t].GetItemKpl() << std::endl;

    }
return EXIT_SUCCESS;
}

Ilmeisesti tarvitaan joku apumuuttuja tyyliin int apu; johon luetaan hakaset toiseen suuntaan ja sitten asennetaan arvo luokkaan/olioon(en tiedä) tyyliin BAR.SetKerros(apu); En vaan tajua enkä jaksa kirjoja avata. Pienestä on nyt kiinni......:)[/t]!

Jokotai [18.12.2010 12:07:00]

#

LUET:

#include <iostream>
#include <fstream>

int main() {
    std::ifstream sisaan("nimi.txt", std::ios::in);
    sisaan.read(minneluetaan, luettavientavujenmaara);
    return EXIT_SUCCESS;
}

DumTom [18.12.2010 12:18:26]

#

Kiitos,koitan illalla vääntää tosta funktion

int NewSaveBarrelFile(char nimi[])
{
std::ofstream ulos(nimi,std::ios::out);
for (int t=0;t<2500;t++)
    {
    ulos << BAR[t].GetOn();// << std::endl;
    ulos << BAR[t].GetType();// << std::endl;
    ulos << BAR[t].GetOpened();// << std::endl;
    ulos << BAR[t].GetKuva();// << std::endl;
    ulos << BAR[t].GetX();// << std::endl;
    ulos << BAR[t].GetY();// << std::endl;
    ulos << BAR[t].GetOX();// << std::endl;
    ulos << BAR[t].GetOY();// << std::endl;
    ulos << BAR[t].GetKerros();// << std::endl;
    ulos << BAR[t].GetItem();// << std::endl;
    ulos << BAR[t].varattu1;// << std::endl;
    ulos << BAR[t].varattu2; //<< std::endl;
    ulos << BAR[t].GetItemKpl();// << std::endl;

    }
return EXIT_SUCCESS;
}


int NewLoadBarrelFile(char nimi[])
{
char apuchar;
std::ifstream sisaan(nimi, std::ios::in);
for (int t=0;t<2500;t++)
    {

sisaan.read(&apuchar,2);
BAR[t].SetOn(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetType(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetOpened(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetKuva(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetX(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetY(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetOX(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetOY(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetX(apuchar);
sisaan.read(&apuchar,2);
BAR[t].SetKerros(apuchar);
sisaan.read(&apuchar,2);
BAR[t].varattu1=apuchar;
sisaan.read(&apuchar,2);
BAR[t].varattu2=apuchar;
sisaan.read(&apuchar,4);
BAR[t].SetItemKpl(apuchar);
return EXIT_SUCCESS;
}
}

Noi kyllä kääntyy mutta tuskin vastaavat toisiaan. Kertokaa missä vikoja????

Deffi [18.12.2010 16:17:43]

#

Yrität lukea char muuttujaan kaksi tai neljä tavua dataa, vaikka siihen mahtuu vain yksi. Toiseksi sulla on lukemisloopin lopussa return, josta seuraa se, että silmukka suoritetaan vain kerran ja sen jälkeen poistutaan funktiosta. Koodi olisi paljon siistimpää, jos käyttäisit streamien >>-operaattoria lukemiseen, aivan kuten käytät <<-operaattoria kirjoittamiseen.

Tässä vielä esimerkki kuinka muuttujien tallentaminen onnistuu C:llä, jos joku tarvitsee.

#include <stdio.h>

int main(int argc, char *argv[])
{
	int eka, toka;
	FILE *pfile;
	eka = 12345678;
	toka = -42;

	// kirjoitus
	if((pfile = fopen("tallennus.dat", "wb")))
	{
		fwrite(&eka, sizeof(int), 1, pfile);
		fwrite(&toka, sizeof(int), 1, pfile);
		fclose(pfile);
		printf("kirjoitettiin %d ja %d\n", eka, toka);
	} else printf("ei aukee\n");

	// luku
	eka = toka = 0;
	if((pfile = fopen("tallennus.dat", "rb")))
	{
		fread(&eka, sizeof(int), 1, pfile);
		fread(&toka, sizeof(int), 1, pfile);
		fclose(pfile);
		printf("luettiin %d ja %d\n", eka, toka);
	} else printf("ei aukee\n");

	return 0;
}

Metabolix [18.12.2010 23:15:16]

#

Deffi kirjoitti:

Koodi olisi paljon siistimpää, jos käyttäisit streamien >>-operaattoria lukemiseen, aivan kuten käytät <<-operaattoria kirjoittamiseen.

Lisäksi tästä olisi sellainen hyöty, että koodi voisi jopa toimia oikein. <<-operaattori tulostaa luvun tekstinä, joten sen perään pitää laittaa vaikkapa väli tai rivinvaihto merkiksi luvun loppumisesta, jotta >>-operaattori saa luettua oikein. Muuten luvuista 12, 34 ja 56 tulostuu tiedostoon 123456, josta on vaikea enää tulkita alkuperäisiä lukuja.

Jos on tarkoitus tallentaa binaarimuodossa, kannattaa tehdä, kuten Deffi yllä neuvoo. (Sama onnistuu myös C++:n virtojen funktioilla read ja write.)

DumTom [19.12.2010 01:03:08]

#

fwrite(&eka, sizeof(int), 1, pfile);

Mitä tuo mystinen ykkönen tekee?
Kirjoitin C-kieliset lataajat ja lukijat tota esimerkkiä seuraillen ja ei toimi,kääntyy kyllä mutta ei toimi.

Grez [19.12.2010 01:20:09]

#

DumTom kirjoitti:

fwrite(&eka, sizeof(int), 1, pfile);

Mitä tuo mystinen ykkönen tekee?

Siis ootko ihan tosissasi että et itse jaksa vaivautua katsomaan funktioiden dokumentaatiota?

count
Number of elements, each one with a size of size bytes.

DumTom [19.12.2010 01:25:11]

#

Siinä on kirjoitus ja luku. Ja peliin ei tallennu mikään oikein.

char SaveBurb(char nimi[])
{
short t,apu;
FILE *C;
//fwrite(str, 1, strlen(str), fp);
if((C = fopen(nimi, "wb+")))
    {
    fwrite(&A.TownName,sizeof(char),strlen(A.TownName),C);

    fwrite(&A.sizex,sizeof(short),1,C);
    fwrite(&A.sizey,sizeof(short),1,C);
    fwrite(&A.AlinKerros,sizeof(short),1,C);
    fwrite(&A.YlinKerros,sizeof(short),1,C);
    fwrite(&A.StartX,sizeof(short),1,C);
    fwrite(&A.StartY,sizeof(short),1,C);
    apu=10;
    fwrite(&apu,sizeof(short),1,C);// aloituskerro
    apu=0;
    fwrite(&apu,sizeof(short),1,C);// paikannumero
    for (short r=A.AlinKerros;r<A.YlinKerros+1;r++)
        {
        apu=0;
        fwrite(&apu,sizeof(short),1,C);// gemmed
         for (short y=0;y<A.sizey;y++)
             {
             for (short x=0;x<A.sizex;x++)
                 {
                 fwrite(&A.Lattia[x][y][r],sizeof(short),1,C);
                 fwrite(&A.Kaluste[x][y][r],sizeof(short),1,C);
                 fwrite(&A.TownRoad[x][y][r],sizeof(short),1,C);
                 fwrite(&A.Barrel[x][y][r],sizeof(short),1,C);

                 }
             }
        }
    fclose(C);
    }else return 1;
return 0;
}
char LoadBurb(char nimi[],char opt)
{
FILE *C;
short t,apu;
    if((C = fopen(nimi, "rb")))
    {

   fread(&A.TownName, sizeof(char), strlen(A.TownName), C);

   fread(&A.sizex, sizeof(short), 1, C);
   fread(&A.sizey, sizeof(short), 1, C);
   fread(&A.AlinKerros, sizeof(short), 1, C);
   fread(&A.YlinKerros, sizeof(short), 1, C);
   fread(&A.StartX, sizeof(short), 1, C);
   fread(&A.StartY, sizeof(short), 1, C);
   fread(&apu, sizeof(short), 1, C); // aloituskerros
   fread(&apu, sizeof(short), 1, C);// paikannumero
   for (short r=A.AlinKerros;r<A.YlinKerros+1;r++)
        {
        apu=0;
        fread(&apu,sizeof(short),1,C);// gemmed
         for (short y=0;y<A.sizey;y++)
             {
             for (short x=0;x<A.sizex;x++)
                 {
                 fread(&A.Lattia[x][y][r],sizeof(short),1,C);
                 fread(&A.Kaluste[x][y][r],sizeof(short),1,C);
                 fread(&A.TownRoad[x][y][r],sizeof(short),1,C);
                 fread(&A.Barrel[x][y][r],sizeof(short),1,C);
                 }
             }
        }
        fclose(C);

    }else return 1;
return 0;
}

Deffi [19.12.2010 02:30:14]

#

Mieti mitä strlen(A.TownName) palauttaa rivillä 47.

DumTom [19.12.2010 02:46:01]

#

Juurikin siinä oli vika.Tein silmukan nimen lukuun ja kirjoitukseen ja nyt lähti homma pelittää.Kiitos kaikille...:)


Sivun alkuun

Vastaus

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

Tietoa sivustosta