Duplication possible:
Quelle est la meilleure façon de filtrer un fichier dans une chaîne std :: ssortingng en c ++?
Dans les langages de script comme Perl, il est possible de lire un fichier dans une variable en une seule fois.
open(FILEHANDLE,$file); $content=;
Quel serait le moyen le plus efficace de le faire en C ++?
Comme ça:
#include #include int main(int argc, char** argv) { std::ifstream ifs("myfile.txt"); std::ssortingng content( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator () ) ); return 0; }
La déclaration
std::ssortingng content( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator () ) );
peut être divisé en
std::ssortingng content; content.assign( (std::istreambuf_iterator(ifs) ), (std::istreambuf_iterator () ) );
ce qui est utile si vous voulez simplement écraser la valeur d’une variable std :: ssortingng existante.
Le plus efficace, mais pas le C ++ serait:
FILE* f = fopen(filename, "r"); // Determine file size fseek(f, 0, SEEK_END); size_t size = ftell(f); char* where = new char[size]; rewind(f); fread(where, sizeof(char), size, f); delete[] where;
#
EDIT – 2 Je viens de tester la variante std::filebuf
également. On dirait qu’il peut être appelé la meilleure approche C ++, même si ce n’est pas une approche C ++, mais plutôt un wrapper. Quoi qu’il en soit, voici le morceau de code qui fonctionne presque aussi vite que le fait C.
std::ifstream file(filename, std::ios::binary); std::streambuf* raw_buffer = file.rdbuf(); char* block = new char[size]; raw_buffer->sgetn(block, size); delete[] block;
J’ai fait un test rapide ici et les résultats suivent. Le test a été effectué en lisant un fichier binary 65536K avec les modes appropriés ( std::ios:binary
et rb
).
[==========] Running 3 tests from 1 test case. [----------] Global test environment set-up. [----------] 4 tests from IO [ RUN ] IO.C_Kotti [ OK ] IO.C_Kotti (78 ms) [ RUN ] IO.CPP_Nikko [ OK ] IO.CPP_Nikko (106 ms) [ RUN ] IO.CPP_Beckmann [ OK ] IO.CPP_Beckmann (1891 ms) [ RUN ] IO.CPP_Neil [ OK ] IO.CPP_Neil (234 ms) [----------] 4 tests from IO (2309 ms total) [----------] Global test environment tear-down [==========] 4 tests from 1 test case ran. (2309 ms total) [ PASSED ] 4 tests.
Le plus efficace consiste à créer un tampon de la taille correcte, puis à lire le fichier dans le tampon.
#include #include int main() { std::ifstream file("Plop"); if (file) { /* * Get the size of the file */ file.seekg(0,std::ios::end); std::streampos length = file.tellg(); file.seekg(0,std::ios::beg); /* * Use a vector as the buffer. * It is exception safe and will be tidied up correctly. * This constructor creates a buffer of the correct length. * Because char is a POD data type it is not initialized. * * Then read the whole file into the buffer. */ std::vector buffer(length); file.read(&buffer[0],length); } }
Il ne devrait y avoir aucun \0
dans les fichiers texte.
#include #include using namespace std; int main(){ fstream f(FILENAME, fstream::in ); ssortingng s; getline( f, s, '\0'); cout << s << endl; f.close(); }
Cela dépend de beaucoup de choses, comme la taille du fichier, son type (texte / binary), etc. Il y a quelque temps, j’ai comparé la fonction suivante avec des versions utilisant des parsingurs streambuf – elle était environ deux fois plus rapide:
unsigned int FileRead( std::istream & is, std::vector & buff ) { is.read( &buff[0], buff.size() ); return is.gcount(); } void FileRead( std::ifstream & ifs, ssortingng & s ) { const unsigned int BUFSIZE = 64 * 1024; // reasoable sized buffer std::vector buffer( BUFSIZE ); while( unsigned int n = FileRead( ifs, buffer ) ) { s.append( &buffer[0], n ); } }
peut-être pas le plus efficace, mais lit les données en une seule ligne:
#include #include #include main(int argc,char *argv[]){ // read standard input into vector: std::vectorv(std::istream_iterator (std::cin), std::istream_iterator ()); std::cout << "read " << v.size() << "chars\n"; }
Voici une méthode basée sur un iterator.
ifstream file("file", ios::binary); ssortingng fileStr; istreambuf_iterator inputIt(file), emptyInputIt back_insert_iterator ssortingngInsert(fileStr); copy(inputIt, emptyInputIt, ssortingngInsert);