C++ Read istream into string with exceptions
Clash 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;
c++ strings stream exception
add a comment |Â
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;
c++ strings stream exception
add a comment |Â
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;
c++ strings stream exception
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;
c++ strings stream exception
edited Feb 24 at 9:42
asked Feb 24 at 0:36
Jive Dadson
26611
26611
add a comment |Â
add a comment |Â
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 thenstatic_cast
it before using it inreserve()
.[code:] Using
std::string::resize()
andstd::istream::read()
to copy from the stream might be faster than usingstd::string::append()
withstd::istreambuf_iterator
s.[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
'srdbuf
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.
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
add a comment |Â
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 thenstatic_cast
it before using it inreserve()
.[code:] Using
std::string::resize()
andstd::istream::read()
to copy from the stream might be faster than usingstd::string::append()
withstd::istreambuf_iterator
s.[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
'srdbuf
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.
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
add a comment |Â
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 thenstatic_cast
it before using it inreserve()
.[code:] Using
std::string::resize()
andstd::istream::read()
to copy from the stream might be faster than usingstd::string::append()
withstd::istreambuf_iterator
s.[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
'srdbuf
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.
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
add a comment |Â
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 thenstatic_cast
it before using it inreserve()
.[code:] Using
std::string::resize()
andstd::istream::read()
to copy from the stream might be faster than usingstd::string::append()
withstd::istreambuf_iterator
s.[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
'srdbuf
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.
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 thenstatic_cast
it before using it inreserve()
.[code:] Using
std::string::resize()
andstd::istream::read()
to copy from the stream might be faster than usingstd::string::append()
withstd::istreambuf_iterator
s.[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
'srdbuf
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.
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
add a comment |Â
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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password