South_Bridge Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 (endret) Jeg har følgende kode som funker: ... std::string str = "Hello World!"; int strSize = str.size(); // // Write file // std::ofstream out; out.open(filename.c_str(), std::ios::binary); out.write( (char *)(&strSize), sizeof(strSize) ); for(int i = 0; i < strSize, i++ ) { out.write( (char *)(&str[i]), 1); } out.close(); ... Åpner jeg fila jeg skriver til får jeg noen merkelige tegn og "Hello World!". Komplette teksten er som følgende: "^L^@^@^@Hello World!". Hva er den første biten før "Hello World!"? den har jo sammenheng med: out.write( (char *)(&strSize), sizeof(strSize) ); Endret 3. mars 2010 av South_Bridge Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 (endret) Tror det hjelper hvis du skriver sizeof(strSize) + 1 sånn at \0 blir tatt med. Hvorfor (char*)&str? Hvorfor ikke str? eller bare str? Endret 3. mars 2010 av GeirGrusom Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Si det... første gang jeg har kikket på det så da bare prøver jeg det jeg finner. Fremdeles et ubesvart spm? Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 (endret) Det er de fire bytene(32-bit) som representerer tallet strSize i binærform. Datamaskinen jobber ikke med tekst eller desimaltall vettu. Endret 3. mars 2010 av GeirGrusom Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Takk for svar. Var det jeg var ute etter. videre: hva om jeg ønsker å lagre et selvspikka objekt? feks struct Person { std::string name; int age; Person(std::string n, int a) { name = n; age = a; } } Binært til en fil og så lese det igjen? Har skrevet funksjonene WriteBinaryTofile(std::fstream &file, Person &p) { file.seekp( 0, std::ios::end); file.write( (char *)&p, sizeof(p) ); } Person ReadBinaryFromFile(std::fstream &file) { file.seekg(0, std::ios:beg); Person p; file.read( (char *)&p, sizeof(p) ); return p; } Men jeg får bare "Segmentation fault" fra kompileren. Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 ostream& operator << (ostream& lval, Person& per) { lval << per.age; lval << per.name; return lval; } ostream& operator >> (ostream& lval, Person& per) { lval >> per.age; lval >> per.name; return lval; } Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Jeg datt av lasset nå... Du utvider operatorene, et tema som er veldig nytt for meg... så hvordan passer det inn i den store sammenhengen i minn aplikasjon? Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 Det gjør sånn at du kan skrive: Person me; me.name = "Ole Olsen" me.age = 30; out << me; For å skrive objektet til en fil. Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Du bruker da fstream? og hvordan setter du den opp? Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 Mulig jeg rotet til med stream typene... Jeg bruker vanligvis fread og fwrite, fordi jeg synes de er enklere å bruke til slikt. Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Okey... noe slikt da: FILE* pFile; pFile.fopen( filename.c_str(), "w"); Person p; p.name = "ole"; p.age = 30; pFile << p; fclose(pFile); Jeg får da følgende errors: main.cpp:57: error: request for member 'fopen' in 'pFile', which is of non-class type 'FILE*' main.cpp:63: error: no match for 'operator' in 'pFile << p' main.cpp:26: note: candidates are: std::ostream& operator<<(std::ostream&, Person&) Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 (endret) ... kødder du med meg eller? Endret 3. mars 2010 av GeirGrusom Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Igrunn ikke... men jeg skal vel kanskje heller bruke fwrite fremfor å klusse med operatorene? Lenke til kommentar
zotbar1234 Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 videre: hva om jeg ønsker å lagre et selvspikka objekt? feks Da er svaret "det kommer an på hva du ønsker å oppnå". Aller først -- "Standard C++ IO streams and locales" av Langer og Kreft er det du ønsker å ta en titt på. I utgangspunktet er det slik at enhver datatype må kunne representeres som en strøm av bytes på en slik måte at det å lese denne representasjonen tilbake gir mening. Legg merke til at "gi mening" kan bety veldig mye rart, alt ettersom hva som er målet med oppgaven. Det GeirGrusom foreslår er tilpasningen av dine egne objekter til "formattert I/O". Hvis du virkelig ønsker dette, så er det å skrive din egen operator<<() og operator>>() veien å gå. Du må da tenke litt på hvordan operator<<() og operator>>() virker sammen med de enkelte datatypene som disse operatorne er allerede definert for. Dersom målet er å lagre en datastruktur for så å kunne lese den tilbake inn i minne, så er ikke formattert IO den beste tilnærmingen. Det vil være mer hensiktsmessig å lage et format som er tilpasset til applikasjonens behov. Wikipedia har garantert veldig mye fint om "serialization" og "marshalling", som er nøkkelord i dette tilfellet. Det du ønsker da er å lage en passende metode i din egen type som skriver "seg selv" ut til den underliggende filen. Da må du ta stilling til slike ting som byte-order, representasjon for basaltypene, hvordan postene innad et objekt blir skilt fra hverandre, hva du skal gjøre med sirkulære datastrukturer, hvordan du skal representere pekere, osv. Så, hva ønsker du egentlig å oppnå? WriteBinaryTofile(std::fstream &file, Person &p) { file.seekp( 0, std::ios::end); file.write( (char *)&p, sizeof(p) ); } Det er *svært* sjelden at det å skrive ut den underliggende byterepresentasjonen til objektet til fil vil gjøre det du vil. Hva om implementasjonen din har masse statusinformasjon i objektet? Hva som GC bruker denne til noe? Eller tracing/profiling-biblioteket? Hva om p inneholder pekere (hvilket en std::string vil høyst sannsynligvis gjøre)? (det å skrive ut en minneadresse (== peker) til en fil innebærer slettes ikke at den adressen lest tilbake vil gi mening). (I tillegg er jeg faktisk usikker på om det å aksessere en Person* gjennom en char* er lovlig. Konverteringen er garantert til å virke. Dvs Person* -> char* -> Person* er lovlig. Men om *(char*) på en Person* er lovlig er jeg litt mindre sikker på). Men jeg får bare "Segmentation fault" fra kompileren. Ja, av grunner nevnt over. Så, hva er det du egentlig vil? Lenke til kommentar
South_Bridge Skrevet 3. mars 2010 Forfatter Del Skrevet 3. mars 2010 Takk for resonsen zotbar1234, du også GeirGrusom. Det jeg vil, og det jeg tenkte å lære meg er å dytte flere ting inn i en fil. Ta world of warcraft som et eksempel. På overflaten har de feks dytta all musikk (av ukjent format) ned i .mpqfiler. .mpq filene er da arkiv/kontainere for media filene. Jeg hadde lyst til å prøve noe av det samme da jeg har et par baller i lufta... hvordan kan jeg feks lage en fil som inneholder flere wavs og/eller kanskje ikke annen media? Jeg tenkte ikke så avansert som blizz har gjort det, men det er en teknikk jeg har hatt lyst til å lære. Lenke til kommentar
Giddion Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 aha et virituelt fil system. Vel det enkleste er bare å legge en array (samt hvor lang arrayen er) av noe alal dette i starten av filen. struct VFSFileEntry { char Name[200]; //Brukes til oppslag int FilePos;//Posisjonen til filen i vfs filen. } Så er det bare å dumpe filene inn i filen og notere seg hvor de starter og slutter. Lenke til kommentar
zotbar1234 Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 Jeg hadde lyst til å prøve noe av det samme da jeg har et par baller i lufta... hvordan kan jeg feks lage en fil som inneholder flere wavs og/eller kanskje ikke annen media? Enten bruke et passende container-format som finnes alt, eller definere ditt eget, og skrive wav-dataene på det formatet. Valget vil antageligvis styres av hva du har tenkt å gjøre med disse wav-filene videre (kan f.eks. tenkes at lydbiblioteket som du bruker for å spille av wav har noen føringer/måter å gjøre det på). Lenke til kommentar
GeirGrusom Skrevet 3. mars 2010 Del Skrevet 3. mars 2010 (endret) edit: opptill flere kom meg i forkjøpet... Ok, ikke noen stor sak egentlig. Det er hovedsaklig to måter å gjøre det på: Du kan separere data fra filstrukturen(Filsystemer som FAT og andre), eller du kan gjøre begge deler i samme struktur (Total Annihilation .TNT filer, .3ds for 3d studio 3.0) Den første kan være litt krunglete, fordi du må bruke filpekere, og det er litt vanskelig å definere filpekere riktig før datene blir skrevet. Men den første har en klar fordel over at all data ikke trengs å traverseres for å danne en struktur fra fila, dog dette er ikke så viktig dersom du bruker memory mapped IO. Men ihvertfall: dann datastrukturer du tror er nyttig (for eksempel header for hver fil, for directory osv.) Lese/skrive til filen er ikke vanskelig. Som sagt bruker jeg fread/fwrite fordi jeg synes diss er litt enklere å bruke. Endret 3. mars 2010 av GeirGrusom Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå