Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7027687
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T00:16:52+00:00 2026-05-28T00:16:52+00:00

I currently do this, and the conversion to std::string at the end take 98%

  • 0

I currently do this, and the conversion to std::string at the end take 98% of the execution time. There must be a better way!

std::string
file2string(std::string filename)
{
    std::ifstream file(filename.c_str());
    if(!file.is_open()){
        // If they passed a bad file name, or one we have no read access to,
        // we pass back an empty string.
        return "";
    }
    // find out how much data there is
    file.seekg(0,std::ios::end);
    std::streampos length = file.tellg();
    file.seekg(0,std::ios::beg);
    // Get a vector that size and
    std::vector<char> buf(length);
    // Fill the buffer with the size
    file.read(&buf[0],length);
    file.close();
    // return buffer as string
    std::string s(buf.begin(),buf.end());
    return s;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T00:16:52+00:00Added an answer on May 28, 2026 at 12:16 am

    Being a big fan of C++ iterator abstraction and the algorithms, I would love the following to be the fasted way to read a file (or any other input stream) into a std::string (and then print the content):

    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <string>
    
    int main()
    {
        std::string s(std::istreambuf_iterator<char>(std::ifstream("file")
                                                     >> std::skipws),
                      std::istreambuf_iterator<char>());
        std::cout << "file='" << s << "'\n";
    }
    

    This certainly is fast for my own implementation of IOStreams but it requires a lot of trickery to actually get it fast. Primarily, it requires optimizing algorithms to cope with segmented sequences: a stream can be seen as a sequence of input buffers. I’m not aware of any STL implementation consistently doing this optimization. The odd use of std::skipws is just to get reference to the just created stream: the std::istreambuf_iterator<char> expects a reference to which the temporary file stream wouldn’t bind.

    Since this probably isn’t the fastest approach, I would be inclined to use std::getline() with a particular “newline” character, i.e. on which isn’t in the file:

    std::string s;
    // optionally reserve space although I wouldn't be too fuzzed about the
    // reallocations because the reads probably dominate the performances
    std::getline(std::ifstream("file") >> std::skipws, s, 0);
    

    This assumes that the file doesn’t contain a null character. Any other character would do as well. Unfortunately, std::getline() takes a char_type as delimiting argument, rather than an int_type which is what the member std::istream::getline() takes for the delimiter: in this case you could use eof() for a character which never occurs (char_type, int_type, and eof() refer to the respective member of char_traits<char>). The member version, in turn, can’t be used because you would need to know ahead of time how many characters are in the file.

    BTW, I saw some attempts to use seeking to determine the size of the file. This is bound not to work too well. The problem is that the code conversion done in std::ifstream (well, actually in std::filebuf) can create a different number of characters than there are bytes in the file. Admittedly, this isn’t the case when using the default C locale and it is possible to detect that this doesn’t do any conversion. Otherwise the best bet for the stream would be to run over the file and determine the number of characters being produced. I actually think that this is what would be needed to be done when the code conversion could something interesting although I don’t think it actually is done. However, none of the examples explicitly set up the C locale, using e.g. std::locale::global(std::locale("C"));. Even with this it is also necessary to open the file in std::ios_base::binary mode because otherwise end of line sequences may be replaced by a single character when reading. Admittedly, this would only make the result shorter, never longer.

    The other approaches using the extraction from std::streambuf* (i.e. those involving rdbuf()) all require that the resulting content is copied at some point. Given that the file may actually be very large this may not be an option. Without the copy this could very well be the fastest approach, however. To avoid the copy, it would be possible to create a simple custom stream buffer which takes a reference to a std::string as constructor argument and directly appends to this std::string:

    #include <fstream>
    #include <iostream>
    #include <string>
    
    class custombuf:
        public std::streambuf
    {
    public:
        custombuf(std::string& target): target_(target) {
            this->setp(this->buffer_, this->buffer_ + bufsize - 1);
        }
    
    private:
        std::string& target_;
        enum { bufsize = 8192 };
        char buffer_[bufsize];
        int overflow(int c) {
            if (!traits_type::eq_int_type(c, traits_type::eof()))
            {
                *this->pptr() = traits_type::to_char_type(c);
                this->pbump(1);
            }
            this->target_.append(this->pbase(), this->pptr() - this->pbase());
            this->setp(this->buffer_, this->buffer_ + bufsize - 1);
            return traits_type::not_eof(c);
        }
        int sync() { this->overflow(traits_type::eof()); return 0; }
    };
    
    int main()
    {
        std::string s;
        custombuf   sbuf(s);
        if (std::ostream(&sbuf)
            << std::ifstream("readfile.cpp").rdbuf()
            << std::flush) {
            std::cout << "file='" << s << "'\n";
        }
        else {
            std::cout << "failed to read file\n";
        }
    }
    

    At least with a suitably chosen buffer I would expect the version to be the fairly fast. Which version is the fastest will certainly depend on the system, the standard C++ library being used, and probably a number of other factors, i.e. you want to measure the performance.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a flash conversion function that I call like this: var key:String=numToChar(keyboardEvent.charCode); currently
There is currently this Prototype code that does a PUT: new Ajax.Request(someUrl, { method:
I currently use this function to wrap executing commands and logging their execution, and
I currently use this handy conversion extension method to do conversions between types: public
Currently I am trying to convert String^ to std::string using marshal_as function (Link: http://msdn.microsoft.com/en-us/library/bb384865.aspx
How do I log inner exception with Log4NET? This is my current conversion pattern:
Currently this expression I ([a-zA-z]\d]{3} returns when the following pattern is true: I AAA
I currently have this working but it requires me to have a static method
The code currently does this and the fgetpos does handle files larger than 4GB
I do not currently have this issue , but you never know, and thought

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.