tags:

views:

319

answers:

7

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: http://stackoverflow.com/questions/116038/what-is-the-best-way-to-slurp-a-file-into-a-stdstring-in-c

A: 

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
In C++, main must return an int. Also you seem to have forgptten the std:: namespace.
anon
And you have forgotten to #include <string>.
anon
yes i forgot to include string header and standard library.But I was using void main function, which don't return any value.If you use int main then it require return value.
Syed Tayyab Ali
@ Syed Tayyab Ali: No, void is not allowed by the standard. Also main() is a special case if you do not specify a return value then 0 will be returned for you.
Martin York
@Martin York: obviously, it is common understanding.
Syed Tayyab Ali
Common, but wrong.
anon
Your loop over-rights the word each time str each iteration. When finished it will be empty or hold the last word.
Martin York
yup last iteration hold last line.or you can put cout<<str; after reading word.it will print on console.
Syed Tayyab Ali
@Syed Tayyab Ali: No. Last iteration hold last WORD. PS. your open ins inside the loop.
Martin York
+3  A: 

Seems like a duplicate:

http://stackoverflow.com/questions/621425/how-do-you-get-a-file-in-c

Anyway, a good reference: http://www.cplusplus.com/doc/tutorial/files/

Dunya Degirmenci
The SO answer you quoted is full of bad code.
anon
Well, I didn't say that the question was answered in a good way :) and there are some other similar questions I found. The second link is the actual answer.
Dunya Degirmenci
+3  A: 
#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.

Kristo
I think this gives the wrong answer if the file is not terminated with a newline.
Steve Jessop
Adding the proper if-test to trap for such a condition is left as an exercise for the OP. ;-)
Kristo
Only mentioning this because the question is asking for minimum code: The C++ standard will assume a "return 0;" if the end of the main function is reached. It's a special case for main()
Shmoopty
+2  A: 

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
A: 

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;
}
anon
+2  A: 

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
Does rdbuf() do anything unsafe if 'ifs' is in a bad state? (e.g., if the file didn't exist)
Kristo
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
A: 

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