Gå til innhold

[Løst][c++] fil till string


Anbefalte innlegg

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
Videoannonse
Annonse

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 av LostOblivion
Lenke til kommentar

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

@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

(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
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

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 av Hans_Henrik
Lenke til kommentar
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
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 :wallbash:) i data (hint: hvorfor?)

Endret av zotbar1234
Lenke til kommentar

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
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
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 :p (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å :p)

Endret av Hans_Henrik
Lenke til kommentar
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);

 

*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
(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 :p)

 

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
(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 :p)

#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 :p] 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 av Hans_Henrik
Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...