C++ Read istream into string with exceptions

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite












Did I cover all the bases? Can this be improved (best practice)?



Edit... I've come up with some improvements. When I tried edit the code, the software complained about too much code and too little blather (paraphrasing). So, here I am blathering. When I have blathered enough, the code below will be the new stuff.



//#include <libdj/istream.h>

#include <istream>
#include <string>
#include <stdexcept>

namespace dj
inline
void append_istream_onto_string(std::istream& inp, std::string &outp)
// Uses inp.seekg(), and inp.tellg() to determine size
// Throws (std::) invalid_argument, runtime_error, bad_alloc, length_error
if (!inp.good())
throw std::invalid_argument
("Input stream is not valid. (read_istream_into_string)");

if (!inp.seekg(0, std::ios::end))
throw std::runtime_error
("Cannot deduce length of input stream. (read_istream_into_string)");

outp.reserve(outp.size() + inp.tellg()); // Throws bad_alloc and length_error
if (!inp.seekg(0, std::ios::beg))
throw std::runtime_error
("Input stream seek failed. (read_istream_into_string)");

outp.append((std::istreambuf_iterator<char>(inp)),
std::istreambuf_iterator<char>());


inline
std::string to_string(std::istream& inp)
std::string ret;
append_istream_onto_string(inp, ret);
return ret;


#include <fstream>

int main()

std::ifstream inp("junk.txt");

std::string buffer;
buffer = "// junk.txtn";
try
//dj::append_istream_onto_string(inp, buffer);
buffer = dj::to_string(inp);
catch (const std::exception &ex)
std::cout << ex.what() << std::endl;

std::cout << buffer << std::endl;







share|improve this question



























    up vote
    5
    down vote

    favorite












    Did I cover all the bases? Can this be improved (best practice)?



    Edit... I've come up with some improvements. When I tried edit the code, the software complained about too much code and too little blather (paraphrasing). So, here I am blathering. When I have blathered enough, the code below will be the new stuff.



    //#include <libdj/istream.h>

    #include <istream>
    #include <string>
    #include <stdexcept>

    namespace dj
    inline
    void append_istream_onto_string(std::istream& inp, std::string &outp)
    // Uses inp.seekg(), and inp.tellg() to determine size
    // Throws (std::) invalid_argument, runtime_error, bad_alloc, length_error
    if (!inp.good())
    throw std::invalid_argument
    ("Input stream is not valid. (read_istream_into_string)");

    if (!inp.seekg(0, std::ios::end))
    throw std::runtime_error
    ("Cannot deduce length of input stream. (read_istream_into_string)");

    outp.reserve(outp.size() + inp.tellg()); // Throws bad_alloc and length_error
    if (!inp.seekg(0, std::ios::beg))
    throw std::runtime_error
    ("Input stream seek failed. (read_istream_into_string)");

    outp.append((std::istreambuf_iterator<char>(inp)),
    std::istreambuf_iterator<char>());


    inline
    std::string to_string(std::istream& inp)
    std::string ret;
    append_istream_onto_string(inp, ret);
    return ret;


    #include <fstream>

    int main()

    std::ifstream inp("junk.txt");

    std::string buffer;
    buffer = "// junk.txtn";
    try
    //dj::append_istream_onto_string(inp, buffer);
    buffer = dj::to_string(inp);
    catch (const std::exception &ex)
    std::cout << ex.what() << std::endl;

    std::cout << buffer << std::endl;







    share|improve this question























      up vote
      5
      down vote

      favorite









      up vote
      5
      down vote

      favorite











      Did I cover all the bases? Can this be improved (best practice)?



      Edit... I've come up with some improvements. When I tried edit the code, the software complained about too much code and too little blather (paraphrasing). So, here I am blathering. When I have blathered enough, the code below will be the new stuff.



      //#include <libdj/istream.h>

      #include <istream>
      #include <string>
      #include <stdexcept>

      namespace dj
      inline
      void append_istream_onto_string(std::istream& inp, std::string &outp)
      // Uses inp.seekg(), and inp.tellg() to determine size
      // Throws (std::) invalid_argument, runtime_error, bad_alloc, length_error
      if (!inp.good())
      throw std::invalid_argument
      ("Input stream is not valid. (read_istream_into_string)");

      if (!inp.seekg(0, std::ios::end))
      throw std::runtime_error
      ("Cannot deduce length of input stream. (read_istream_into_string)");

      outp.reserve(outp.size() + inp.tellg()); // Throws bad_alloc and length_error
      if (!inp.seekg(0, std::ios::beg))
      throw std::runtime_error
      ("Input stream seek failed. (read_istream_into_string)");

      outp.append((std::istreambuf_iterator<char>(inp)),
      std::istreambuf_iterator<char>());


      inline
      std::string to_string(std::istream& inp)
      std::string ret;
      append_istream_onto_string(inp, ret);
      return ret;


      #include <fstream>

      int main()

      std::ifstream inp("junk.txt");

      std::string buffer;
      buffer = "// junk.txtn";
      try
      //dj::append_istream_onto_string(inp, buffer);
      buffer = dj::to_string(inp);
      catch (const std::exception &ex)
      std::cout << ex.what() << std::endl;

      std::cout << buffer << std::endl;







      share|improve this question













      Did I cover all the bases? Can this be improved (best practice)?



      Edit... I've come up with some improvements. When I tried edit the code, the software complained about too much code and too little blather (paraphrasing). So, here I am blathering. When I have blathered enough, the code below will be the new stuff.



      //#include <libdj/istream.h>

      #include <istream>
      #include <string>
      #include <stdexcept>

      namespace dj
      inline
      void append_istream_onto_string(std::istream& inp, std::string &outp)
      // Uses inp.seekg(), and inp.tellg() to determine size
      // Throws (std::) invalid_argument, runtime_error, bad_alloc, length_error
      if (!inp.good())
      throw std::invalid_argument
      ("Input stream is not valid. (read_istream_into_string)");

      if (!inp.seekg(0, std::ios::end))
      throw std::runtime_error
      ("Cannot deduce length of input stream. (read_istream_into_string)");

      outp.reserve(outp.size() + inp.tellg()); // Throws bad_alloc and length_error
      if (!inp.seekg(0, std::ios::beg))
      throw std::runtime_error
      ("Input stream seek failed. (read_istream_into_string)");

      outp.append((std::istreambuf_iterator<char>(inp)),
      std::istreambuf_iterator<char>());


      inline
      std::string to_string(std::istream& inp)
      std::string ret;
      append_istream_onto_string(inp, ret);
      return ret;


      #include <fstream>

      int main()

      std::ifstream inp("junk.txt");

      std::string buffer;
      buffer = "// junk.txtn";
      try
      //dj::append_istream_onto_string(inp, buffer);
      buffer = dj::to_string(inp);
      catch (const std::exception &ex)
      std::cout << ex.what() << std::endl;

      std::cout << buffer << std::endl;









      share|improve this question












      share|improve this question




      share|improve this question








      edited Feb 24 at 9:42
























      asked Feb 24 at 0:36









      Jive Dadson

      26611




      26611




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote



          accepted










          Streams are awful. Don't use them. (Joking, but I wish I had a viable alternative to recommend for basic file input. C++ is pathetic in this area.)



          • [code:] tellg() returns a signed type, with -1 as an error value. You might like to check that, and then static_cast it before using it in reserve().


          • [code:] Using std::string::resize() and std::istream::read() to copy from the stream might be faster than using std::string::append() with std::istreambuf_iterators.


          • [design(bug?):] Seeking to the end of the file like that may not work. On Windows, for example, if a file is opened in text mode, the ctrl-z (alt026) character is treated as the end of the file (even though it isn't). As I understand it, you have to use ignore() to find the real end of the file instead.


          • [design:] I doubt it's worth it to create a function to append a string directly. Loading into a string, then appending is probably fast enough. (What if you want to prepend or insert... suddenly you need more functions that basically do the same thing).


          • Write unit tests! Something like this needs a whole bunch of tests that save a string to a file, then load a string and compare the results (binary mode, text mode, special characters, etc.).


          The whole article in the link above is useful, but the summary section at the end describes 3 reasonable alternatives for reading from a file stream:



          • Put the istream's rdbuf into a stringstream, then use the .str() function to get a string. This involves extra copying, but is simplest, and should be quick enough.

          • Use .ignore() to find the end of the file, then read the whole thing at once. No extra copies in memory (good for large files), but involves reading the file twice.

          • Read chunks into a std::deque and then copy. Works where it's not possible to seek in the stream.





          share|improve this answer





















          • Good stuff. ...
            – Jive Dadson
            Mar 3 at 17:23










          • I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
            – Jive Dadson
            Mar 4 at 9:05











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188240%2fc-read-istream-into-string-with-exceptions%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          1
          down vote



          accepted










          Streams are awful. Don't use them. (Joking, but I wish I had a viable alternative to recommend for basic file input. C++ is pathetic in this area.)



          • [code:] tellg() returns a signed type, with -1 as an error value. You might like to check that, and then static_cast it before using it in reserve().


          • [code:] Using std::string::resize() and std::istream::read() to copy from the stream might be faster than using std::string::append() with std::istreambuf_iterators.


          • [design(bug?):] Seeking to the end of the file like that may not work. On Windows, for example, if a file is opened in text mode, the ctrl-z (alt026) character is treated as the end of the file (even though it isn't). As I understand it, you have to use ignore() to find the real end of the file instead.


          • [design:] I doubt it's worth it to create a function to append a string directly. Loading into a string, then appending is probably fast enough. (What if you want to prepend or insert... suddenly you need more functions that basically do the same thing).


          • Write unit tests! Something like this needs a whole bunch of tests that save a string to a file, then load a string and compare the results (binary mode, text mode, special characters, etc.).


          The whole article in the link above is useful, but the summary section at the end describes 3 reasonable alternatives for reading from a file stream:



          • Put the istream's rdbuf into a stringstream, then use the .str() function to get a string. This involves extra copying, but is simplest, and should be quick enough.

          • Use .ignore() to find the end of the file, then read the whole thing at once. No extra copies in memory (good for large files), but involves reading the file twice.

          • Read chunks into a std::deque and then copy. Works where it's not possible to seek in the stream.





          share|improve this answer





















          • Good stuff. ...
            – Jive Dadson
            Mar 3 at 17:23










          • I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
            – Jive Dadson
            Mar 4 at 9:05















          up vote
          1
          down vote



          accepted










          Streams are awful. Don't use them. (Joking, but I wish I had a viable alternative to recommend for basic file input. C++ is pathetic in this area.)



          • [code:] tellg() returns a signed type, with -1 as an error value. You might like to check that, and then static_cast it before using it in reserve().


          • [code:] Using std::string::resize() and std::istream::read() to copy from the stream might be faster than using std::string::append() with std::istreambuf_iterators.


          • [design(bug?):] Seeking to the end of the file like that may not work. On Windows, for example, if a file is opened in text mode, the ctrl-z (alt026) character is treated as the end of the file (even though it isn't). As I understand it, you have to use ignore() to find the real end of the file instead.


          • [design:] I doubt it's worth it to create a function to append a string directly. Loading into a string, then appending is probably fast enough. (What if you want to prepend or insert... suddenly you need more functions that basically do the same thing).


          • Write unit tests! Something like this needs a whole bunch of tests that save a string to a file, then load a string and compare the results (binary mode, text mode, special characters, etc.).


          The whole article in the link above is useful, but the summary section at the end describes 3 reasonable alternatives for reading from a file stream:



          • Put the istream's rdbuf into a stringstream, then use the .str() function to get a string. This involves extra copying, but is simplest, and should be quick enough.

          • Use .ignore() to find the end of the file, then read the whole thing at once. No extra copies in memory (good for large files), but involves reading the file twice.

          • Read chunks into a std::deque and then copy. Works where it's not possible to seek in the stream.





          share|improve this answer





















          • Good stuff. ...
            – Jive Dadson
            Mar 3 at 17:23










          • I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
            – Jive Dadson
            Mar 4 at 9:05













          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          Streams are awful. Don't use them. (Joking, but I wish I had a viable alternative to recommend for basic file input. C++ is pathetic in this area.)



          • [code:] tellg() returns a signed type, with -1 as an error value. You might like to check that, and then static_cast it before using it in reserve().


          • [code:] Using std::string::resize() and std::istream::read() to copy from the stream might be faster than using std::string::append() with std::istreambuf_iterators.


          • [design(bug?):] Seeking to the end of the file like that may not work. On Windows, for example, if a file is opened in text mode, the ctrl-z (alt026) character is treated as the end of the file (even though it isn't). As I understand it, you have to use ignore() to find the real end of the file instead.


          • [design:] I doubt it's worth it to create a function to append a string directly. Loading into a string, then appending is probably fast enough. (What if you want to prepend or insert... suddenly you need more functions that basically do the same thing).


          • Write unit tests! Something like this needs a whole bunch of tests that save a string to a file, then load a string and compare the results (binary mode, text mode, special characters, etc.).


          The whole article in the link above is useful, but the summary section at the end describes 3 reasonable alternatives for reading from a file stream:



          • Put the istream's rdbuf into a stringstream, then use the .str() function to get a string. This involves extra copying, but is simplest, and should be quick enough.

          • Use .ignore() to find the end of the file, then read the whole thing at once. No extra copies in memory (good for large files), but involves reading the file twice.

          • Read chunks into a std::deque and then copy. Works where it's not possible to seek in the stream.





          share|improve this answer













          Streams are awful. Don't use them. (Joking, but I wish I had a viable alternative to recommend for basic file input. C++ is pathetic in this area.)



          • [code:] tellg() returns a signed type, with -1 as an error value. You might like to check that, and then static_cast it before using it in reserve().


          • [code:] Using std::string::resize() and std::istream::read() to copy from the stream might be faster than using std::string::append() with std::istreambuf_iterators.


          • [design(bug?):] Seeking to the end of the file like that may not work. On Windows, for example, if a file is opened in text mode, the ctrl-z (alt026) character is treated as the end of the file (even though it isn't). As I understand it, you have to use ignore() to find the real end of the file instead.


          • [design:] I doubt it's worth it to create a function to append a string directly. Loading into a string, then appending is probably fast enough. (What if you want to prepend or insert... suddenly you need more functions that basically do the same thing).


          • Write unit tests! Something like this needs a whole bunch of tests that save a string to a file, then load a string and compare the results (binary mode, text mode, special characters, etc.).


          The whole article in the link above is useful, but the summary section at the end describes 3 reasonable alternatives for reading from a file stream:



          • Put the istream's rdbuf into a stringstream, then use the .str() function to get a string. This involves extra copying, but is simplest, and should be quick enough.

          • Use .ignore() to find the end of the file, then read the whole thing at once. No extra copies in memory (good for large files), but involves reading the file twice.

          • Read chunks into a std::deque and then copy. Works where it's not possible to seek in the stream.






          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered Mar 3 at 12:53









          user673679

          1,042518




          1,042518











          • Good stuff. ...
            – Jive Dadson
            Mar 3 at 17:23










          • I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
            – Jive Dadson
            Mar 4 at 9:05

















          • Good stuff. ...
            – Jive Dadson
            Mar 3 at 17:23










          • I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
            – Jive Dadson
            Mar 4 at 9:05
















          Good stuff. ...
          – Jive Dadson
          Mar 3 at 17:23




          Good stuff. ...
          – Jive Dadson
          Mar 3 at 17:23












          I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
          – Jive Dadson
          Mar 4 at 9:05





          I have hated std::streams since before they were made standard. I intend to act upon your criticism. I appreciate it enormously. Watch this space.
          – Jive Dadson
          Mar 4 at 9:05













           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188240%2fc-read-istream-into-string-with-exceptions%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation