0

What is the minimum code required to read a file and assign its contents to a string in c++? I did read a lot of tutorials that worked but they were all different in a way so i am trying to see why, so if you could please include some explanatory comments that would be great.


Related: What is the best way to read an entire file into a std::string in C++?

Community
  • 1
  • 1
Babiker
  • 16,998
  • 26
  • 70
  • 119

6 Answers6

2
#include <fstream>
#include <string>

int main()
{
    std::ifstream file("myfile.txt");  // open the file
    std::string line, whole_file;

    // Read one line at a time from 'file' and store the result
    // in the string called 'line'.
    while (std::getline(file, line))
    {
        // Append each line together so the entire file will
        // be in one string.
        whole_file += line;
        whole_file += '\n';
    }

    return 0;
    // 'file' is closed automatically when the object goes out of scope.
}

A couple of things to note here. getline() returns a reference to the stream object, which fails the while-test if anything bad happens or if you reach the end of the file. Also, the trailing newline is not included in the string, so you have to append it manually.

Michael Kristofik
  • 31,476
  • 15
  • 72
  • 121
2

The shortest code: (not effecient)

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <fstream>

int main()
{
    std::ifstream f("plop");


    std::string buffer;
    std::copy(std::istreambuf_iterator<char>(f),
              std::istreambuf_iterator<char>(),
              std::back_inserter(buffer));
}

How I would probably do it:

#include <iostream>
#include <string>    
#include <vector>
#include <algorithm>
#include <iterator>
#include <fstream>



int main()
{
    // Find the size of the file
    std::ifstream       file("Plop");
    file.seekg(0,std::ios_base::end);

    std::streampos      size    = file.tellg();

    // Read the file in one go.
    file.seekg(0);
    std::vector<char>   buffer(size); // pre-szie the vector.
    file.read(&buffer[0],size);

    // or

    // Until the next version of the standard I don't think string gurantees contigious storage.
    // But all the current versions I know do use continious storage so it should workd.
    file.seekg(0);
    std::string         buffer1(size);
    file.read(&buffer1[0],size);
}
Martin York
  • 234,851
  • 74
  • 306
  • 532
2

I'm not seeing as much:

#include <fstream>
#include <sstream>
#include <string>
using namespace std;

int main() {
    ifstream ifs("filename");
    stringstream ss;
    ss << ifs.rdbuf();
    string s = ss.str();
}

... as I'd expect. You'd want some error-checking too.

Konrad Rudolph gave this as the answer to the "related question" linked above. I suppose this isn't a duplicate, since this asks for the shortest code, but the answer is the same either way. So I repost it here as wiki.

Steve Jessop
  • 257,525
  • 32
  • 431
  • 672
  • Does rdbuf() do anything unsafe if 'ifs' is in a bad state? (e.g., if the file didn't exist) – Michael Kristofik May 09 '09 at 01:29
  • Oops, I accidentally edited out my "you'd want some error-checking too" comment. Experimentally, on my implementation you end up with an empty string, so it doesn't do anything bad but you don't catch the fault with the above code. – Steve Jessop May 09 '09 at 13:35
1

I am reading a word from each line.

    #include<fstream>
    #include<string>
    using namespace std;    
    int main(int argc, char **argv)
    {
    fstream inFile;
    string str;
    while(!inFile.eof())
    {
    inFile.open("file.txt");
    infile>>str;
    }
    inFile.close();
    return 0;
    }
Syed Tayyab Ali
  • 3,467
  • 7
  • 28
  • 35
0

This is longer than the short solutions, but is possibly slightly more efficient as it does a bit less copying - I haven't done any timing comparisons though:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;;

unsigned int FileRead( istream & is, vector <char> & buff ) {
    is.read( &buff[0], buff.size() );
    return is.gcount();
}

int main() {
    ifstream ifs( "afile.dat", ios::binary );
    const unsigned int BUFSIZE = 64 * 1024; 
    std::vector <char> buffer( BUFSIZE );
    unsigned int n;
    string s;
    while( n = FileRead( ifs, buffer ) ) {
        s.append( &buffer[0], n );
    }

    cout <<  s;
}
0

If you know that your file contains text, then you can use STLSoft's platformstl::memory_mapped_file:

platformstl::memory_mapped_file file("your-file-name");
std::string contents(static_cast<char const*>(file.memory()), file.size());

or

platformstl::memory_mapped_file file("your-file-name");
std::wstring contents(static_cast<wchar_t const*>(file.memory()), 
          file.size() / sizeof(wchar_t));

On WIndows, that will leave your string containing \r\n sequences, so you could instead use the winstl::load_text_file() function:

std::string contents;
winstl::load_text_file("your-file-name", contents);

If you want it loaded into a collection of lines, then use platformstl::read_lines():

platformstl::basic_file_lines<char> lines("your-file-name");
size_t n = lines.size();
std::string line3 = lines[3];
dcw
  • 3,371
  • 2
  • 20
  • 30