Read the contents of a file in a line in C ++

Possible duplicate:
What is the best way to split a file into std :: string in C ++?

In scripting languages ​​such as Perl, you can read a file in a variable in one shot.

open(FILEHANDLE,$file); $content=<FILEHANDLE>; 

What would be the most efficient way to do this in C ++?

+58
c ++ string file-io
May 26 '10 at 11:36 a.m.
source share
7 answers

Like this:

 #include <fstream> #include <string> int main(int argc, char** argv) { std::ifstream ifs("myfile.txt"); std::string content( (std::istreambuf_iterator<char>(ifs) ), (std::istreambuf_iterator<char>() ) ); return 0; } 

Statement

  std::string content( (std::istreambuf_iterator<char>(ifs) ), (std::istreambuf_iterator<char>() ) ); 

can be divided into

 std::string content; content.assign( (std::istreambuf_iterator<char>(ifs) ), (std::istreambuf_iterator<char>() ) ); 

which is useful if you just want to overwrite the value of an existing variable std :: string.

+125
May 26 '10 at 11:48 a.m.
source share

The most efficient but not C ++ way:

  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

Just tested the std::filebuf . It seems that it can be called the best C ++ approach, although this is not quite an approach in C ++, but rather a shell. Anyway, here is a piece of code that runs almost as fast as regular 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; 

I did a quick test here and the results follow. The test was conducted while reading the 65536K binary with the corresponding modes ( std::ios:binary and 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. 
+32
May 26 '10 at 11:46 a.m.
source share

The most efficient way is to create a buffer of the correct size and then read the file into the buffer.

 #include <fstream> #include <vector> 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<char> buffer(length); file.read(&buffer[0],length); } } 
+11
May 26 '10 at 14:23
source share

Text files should not have \0 .

 #include<iostream> #include<fstream> using namespace std; int main(){ fstream f(FILENAME, fstream::in ); string s; getline( f, s, '\0'); cout << s << endl; f.close(); } 
+5
May 26 '10 at 11:46
source share

It depends on many things, such as the size of the file, what its type is (text / binary), etc. Some time ago, I compared the following function with versions using streambuf iterators - it was about twice as fast:

 unsigned int FileRead( std::istream & is, std::vector <char> & buff ) { is.read( &buff[0], buff.size() ); return is.gcount(); } void FileRead( std::ifstream & ifs, string & s ) { const unsigned int BUFSIZE = 64 * 1024; // reasoable sized buffer std::vector <char> buffer( BUFSIZE ); while( unsigned int n = FileRead( ifs, buffer ) ) { s.append( &buffer[0], n ); } } 
+2
May 26 '10 at 11:54 a.m.
source share

perhaps not the most efficient, but it reads the data in one line:

 #include<iostream> #include<vector> #include<iterator> main(int argc,char *argv[]){ // read standard input into vector: std::vector<char>v(std::istream_iterator<char>(std::cin), std::istream_iterator<char>()); std::cout << "read " << v.size() << "chars\n"; } 
+1
May 26 '10 at 11:44
source share

It uses an iterator based method.

 ifstream file("file", ios::binary); string fileStr; istreambuf_iterator<char> inputIt(file), emptyInputIt back_insert_iterator<string> stringInsert(fileStr); copy(inputIt, emptyInputIt, stringInsert); 
+1
May 26 '10 at 11:45 a.m.
source share



All Articles