Hans_Henrik Skrevet 22. mai 2009 Del Skrevet 22. mai 2009 jeg trenger å lese innholdet i en fil, og legge det til en std::string... byte-for-byte noen som vet hvordan jeg kan gjøre dette? (jeg gjorde noe lignende en gang, med std::ifstream og std::getline() men er ikke bra på "binær filer" + at den tar till neste newline) Lenke til kommentar
LostOblivion Skrevet 22. mai 2009 Del Skrevet 22. mai 2009 (endret) Kan ikke C++ så godt, men her ender du opp med en std::string som inneholder en fil. Husk at å lagre en hel fil i minnet på en gang, ikke er veldig smart, siden filer kan være veldig store. Dette er for det meste skrevet i C. #include <stdio.h> #include <iostream> using namespace std; int main() { char *filepath = "path/to/file.txt"; char *buf; string strbuf; fpos_t length; FILE *fstream; fstream = fopen(filepath, "r"); if (fstream == 0) { perror(filepath); exit(-1); } fseek(fstream, 0, SEEK_END); fgetpos(fstream, &length); rewind(fstream); buf = (char *)malloc(length); fread(buf, sizeof(char), length, fstream); strbuf = string(buf); free(buf); fclose(fstream); /* Have file in string strbuf. */ return 0; } Endret 22. mai 2009 av LostOblivion Lenke til kommentar
Zolo Skrevet 23. mai 2009 Del Skrevet 23. mai 2009 Noe slik du vil? #include <fstream> #include <string> #include <iostream> int main(){ std::fstream fs; fs.open("file.txt"); char c; std::string str; while(fs >> c){ str += c; //std::cout << c << std::endl; } std::cout << str; return 0; } Lenke til kommentar
Hans_Henrik Skrevet 23. mai 2009 Forfatter Del Skrevet 23. mai 2009 (endret) EDIT: kan en admin/mod vennligst fjerne denne meldingen? (original inneholdt nøyaktig samme melding som 1 under meg, kjører nå på ett net med ~25% packet-loss på 32-bytes packer... ) Endret 23. mai 2009 av Hans_Henrik Lenke til kommentar
Hans_Henrik Skrevet 23. mai 2009 Forfatter Del Skrevet 23. mai 2009 @LostOblivion fra hva jeg kunne se i den koden, så putter den hele programmet in i memory på en gang @Zolo yup! forresten, vill den "while" 'en bli terminert/stoppet/terminated {sorry, er ikke helt sikker på hva man skal kalle det, og er trøtt..} med 0x00 eller 0x0D eller 0x0A ? (kan ikke teste det nå) Lenke til kommentar
LostOblivion Skrevet 23. mai 2009 Del Skrevet 23. mai 2009 Ja, det gjør koden min, men jeg sier at dette ikke er veldig smart, derfor grunnen til at man burde behandle filer i stykkevis. Men du ville kanskje skrive ut filinnholdet til stdout, og da er det jo greit. Lenke til kommentar
Hans_Henrik Skrevet 24. mai 2009 Forfatter Del Skrevet 24. mai 2009 (skrev deler av denne koden igår mens jeg var trøtt, men kan ikke finne _feilen_ i våken-modus heller...) hvorfor feiler denne? std::string OutputFile; OutputFile=argv[2]; OutputFile+=".ds"; char c; std::string FileString; while(InputFileStream >> c) { FileCounter++; // its an int OutputFileStream.open(OutputFile.c_str()+FileCounter/*this had no effect: , std::ofstream::out | std::ofstream::in | std::ofstream::binary*/); //OutputtFile is a string FileString += c; OutputFileStream << FileString; OutputFileStream.close(); // std::cout << c << std::endl; } (den lager en fil, med .ds, men ingen nummer, og skrive ingen ting till filen.) fulle koden her: http://pastebin.com/f4c9f575b Lenke til kommentar
Zolo Skrevet 24. mai 2009 Del Skrevet 24. mai 2009 FileCounter++; // its an int OutputFileStream.open(OutputFile.c_str()+FileCounter/*this had no effect: , std::ofstream::out | std::ofstream::in | std::ofstream::binary*/); FileCounter er en int.. det gir feilen når du åpner filen i linjen nedenfor. Du må konverterer den til en string før du bruker den i filnavnet. Lenke til kommentar
Hans_Henrik Skrevet 24. mai 2009 Forfatter Del Skrevet 24. mai 2009 (endret) ja, takk (fixet det med en itoa, forresten, er det bare meg som synes det er rart at den "lagde filen" men ikke "skrev til den"?) men nå er problemet, "While" blir stoppet hvis "c" blir hex koden 0D (0x0D) noen ide om hvordan jeg kan fixe det? Endret 24. mai 2009 av Hans_Henrik Lenke til kommentar
zotbar1234 Skrevet 25. mai 2009 Del Skrevet 25. mai 2009 men nå er problemet, "While" blir stoppet hvis "c" blir hex koden 0D(0x0D) noen ide om hvordan jeg kan fixe det? Hvis du trenger rå fil->string funksjon, så er formattert I/O Feil Måte[tm] å angripe dette på. Det er mer hensiktsmessig å bruke get() eller stream iterators: #include <iostream> #include <string> #include <iterator> #include <fstream> int main( int argc, char *argv[] ) { using namespace std; // Version 1 -- get(). ifstream ifs(argv[1]); string content; ifstream::char_type c; while ( ifs.get(c) ) content += c; cout << "file " << argv[1] << " contains:\n"; cout << content; ifs.close(); // Version 2 - I/O streams pr0n ifs.open(argv[1]); string content2((istreambuf_iterator<ifstream::char_type>(ifs)), (istreambuf_iterator<ifstream::char_type>())); cout << content2; } Lenke til kommentar
zotbar1234 Skrevet 25. mai 2009 Del Skrevet 25. mai 2009 (endret) fread(buf, sizeof(char), length, fstream); strbuf = string(buf); sizeof(char) er stipulert til 1. string(const char*) er en litt fiffig sak, når det forekommer nulbyte (møkkaforumprogramvare som ikke takler quote-backslash-null-quote ) i data (hint: hvorfor?) Endret 25. mai 2009 av zotbar1234 Lenke til kommentar
LostOblivion Skrevet 25. mai 2009 Del Skrevet 25. mai 2009 Oja, det tenkte jeg ikke på. Men det å "legge innholdet i en fil inn i en std::string" er vel egentlig litt tafatt i utgangspunktet... Det du nok er ute etter er å legge filen inn i et buffer, for så å kunne bearbeide filen derfra. Det jeg gjør ovenfor legger hele innholdet i filen inn i minnet der hvor buf peker. Du har nå buf som er et buffer av hele filen. Dette kan da ikke behandles som en C string overhodet, ettersom det ikke er en C string, men et databuffer. Men husk å ikke gjøre dette i praksis med filer, husk å behandle filer stykkevis. Lenke til kommentar
zotbar1234 Skrevet 25. mai 2009 Del Skrevet 25. mai 2009 Oja, det tenkte jeg ikke på. Men det å "legge innholdet i en fil inn i en std::string" er vel egentlig litt tafatt i utgangspunktet... Det kommer vel an på hva filen inneholder? Uansett, da jeg bladde i standarden på vei etter funksjoner, slo deg meg hvor komplisert en triviell oppgave egentlig er. Det burde ikke være nødvendig å ha sex med streambuf-iteratorer for å få til en konseptuelt sett veldig enkel oppgave (file(name).read() i Python. Hallo, liksom!) Lenke til kommentar
GeirGrusom Skrevet 26. mai 2009 Del Skrevet 26. mai 2009 Er det ikke bedre å bruke getline istedet for å lese én og én bokstav? Lenke til kommentar
zotbar1234 Skrevet 26. mai 2009 Del Skrevet 26. mai 2009 Er det ikke bedre å bruke getline istedet for å lese én og én bokstav? Ikke når EOL kan være blant data og man ønsker å ta vare på det. Lenke til kommentar
Hans_Henrik Skrevet 27. mai 2009 Forfatter Del Skrevet 27. mai 2009 (endret) men nå er problemet, "While" blir stoppet hvis "c" blir hex koden 0D(0x0D) noen ide om hvordan jeg kan fixe det? Hvis du trenger rå fil->string funksjon, så er formattert I/O Feil Måte[tm] å angripe dette på. Det er mer hensiktsmessig å bruke get() eller stream iterators: #include <iostream> #include <string> #include <iterator> #include <fstream> int main( int argc, char *argv[] ) { using namespace std; // Version 1 -- get(). ifstream ifs(argv[1]); string content; ifstream::char_type c; while ( ifs.get(c) ) content += c; cout << "file " << argv[1] << " contains:\n"; cout << content; ifs.close(); // Version 2 - I/O streams pr0n ifs.open(argv[1]); string content2((istreambuf_iterator<ifstream::char_type>(ifs)), (istreambuf_iterator<ifstream::char_type>())); cout << content2; } Begge feiler når "c" blir 0x0D (eller... muligens stringen... += c; feiler...) (med mindre jeg gjorde en feil i denne koden, når jeg _bare_ la till ofstream http://pastebin.com/m5da633af ) edit: jeg bruker default kompileren som kommer med MSVC 2008, har det noe med saken og gjøre? edit 2: byttet ut med while ( ifs.get© || c==0x0D || c==0x0A) og tilsynelatende, hang den seg når den skulle +=c; og den var 0x0D eller 0x0A {vell, jeg hakke PEILING på hvordan jeg bruker debugger, og jeg vet ikke om den faktisk hang seg på "==0x0D" eller "content +c;" men 1 av dem.. ingen crash, bare "bruker 50% cpu hele tiden, og blir ikke ferdig"} edit 3: eh... tror jeg fikk det till og funke med zotbar1234 "v1" (tror løsningen var ifs.open(argv[1], ifstream::in | ifstream::binary); ofs.open(ofsname.c_str(), ofstream::out | ofstream::binary); ) http://pastebin.com/d63f84349 ser ut till og fungere... (vill trykke på "løst" når jeg for testet det fullt, er på skolen nå ) Endret 27. mai 2009 av Hans_Henrik Lenke til kommentar
zotbar1234 Skrevet 28. mai 2009 Del Skrevet 28. mai 2009 eh... tror jeg fikk det till og funke medzotbar1234 "v1" (tror løsningen var ifs.open(argv[1], ifstream::in | ifstream::binary); ofs.open(ofsname.c_str(), ofstream::out | ofstream::binary); *facepalm* jeg glemmer stadig vekk når jeg har med dustete platformer å gjøre. Ja, binary er nok tingen her (dog, jeg ser ingen grunn til at iterator-løsningen ikke skulle virke). Lenke til kommentar
Hans_Henrik Skrevet 28. mai 2009 Forfatter Del Skrevet 28. mai 2009 (dog, jeg ser ingen grunn til at iterator-løsningen ikke skulle virke). vell.. den gjør ikke det når filen inneholder 0x0D (vet ikke hvorfor da ) (bruker default c++ compiler som kommer med Visual Studio 2008) her er en test-fil hvis du vill prøve selv http://www.speedyshare.com/906535122.html Lenke til kommentar
zotbar1234 Skrevet 28. mai 2009 Del Skrevet 28. mai 2009 (dog, jeg ser ingen grunn til at iterator-løsningen ikke skulle virke). vell.. den gjør ikke det når filen inneholder 0x0D (vet ikke hvorfor da ) Det er bare tøys: $ ./a.out source.pdb output.pdb $ md5sum !!:1 !!:2 $ md5sum source.pdb output.pdb 2fa3dd20606c9e1d4d3bc6554da5f647 source.pdb 2fa3dd20606c9e1d4d3bc6554da5f647 output.pdb $ cat reading.cpp #include <iostream> #include <string> #include <iterator> #include <fstream> #include <algorithm> int main( int argc, char *argv[] ) { using namespace std; ifstream ifs(argv[1]); string content((istreambuf_iterator<ifstream::char_type>(ifs)), (istreambuf_iterator<ifstream::char_type>())); ofstream ofs(argv[2]); copy(content.begin(), content.end(), ostreambuf_iterator<ofstream::char_type>(ofs)); ofs.close(); } $ Lenke til kommentar
Hans_Henrik Skrevet 29. mai 2009 Forfatter Del Skrevet 29. mai 2009 (endret) (dog, jeg ser ingen grunn til at iterator-løsningen ikke skulle virke). vell.. den gjør ikke det når filen inneholder 0x0D (vet ikke hvorfor da ) #include <iostream> #include <string> #include <iterator> #include <fstream> #include <algorithm> int main( int argc, char *argv[] ) { using namespace std; ifstream ifs(argv[1]); string content((istreambuf_iterator<ifstream::char_type>(ifs)), (istreambuf_iterator<ifstream::char_type>())); ofstream ofs(argv[2]); copy(content.begin(), content.end(), ostreambuf_iterator<ofstream::char_type>(ofs)); ofs.close(); } $[/code] Muligens den gjør det med cygwin/GCC [eller hva du nå bruker ] men ikke den kompilator som kommer med MS Visual Studio 2008 (noen som kan navnet på den kompileren btw?) se her hva programmet gjør med filen http://www.speedyshare.com/206894785.html (inkludert kompilerte filen, kildekoden {nøyaktig den du postet i quoten btw}, Input filen, og Output filen) Endret 29. mai 2009 av Hans_Henrik 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å