Using the following code to extract a string from a std::istream :
#include <sstream>
#include <iostream>
void parse(std::istream & is, std::string & out)
{
is >> out;
}
int main(int argc, char** argv)
{
if (argc>1)
{
std::istringstream is(argv[1]);
std::string out("__INIT__");
std::cout << "good:" << is.good() << " fail:"<< is.fail() << " eof:"<< is.eof() << " in_avail:"<< is.rdbuf()->in_avail() << " value:" << out << std::endl;
parse(is, out);
std::cout << "good:" << is.good() << " fail:"<< is.fail() << " eof:"<< is.eof() << " in_avail:"<< is.rdbuf()->in_avail() << " value:" << out << std::endl;
}
}
With a non-empty string the output looks like :
$./a.out "TEST"
good:1 fail:0 eof:0 in_avail:4 value:__INIT__
good:0 fail:0 eof:1 in_avail:0 value:TEST
With an empty string the output looks like :
$./a.out ""
good:1 fail:0 eof:0 in_avail:0 value:__INIT__
good:0 fail:1 eof:1 in_avail:0 value:__INIT__
Instead of this, I would expect :
good:1 fail:0 eof:0 in_avail:0 value:__INIT__
good:0 fail:0 eof:1 in_avail:0 value:
The operator>> does not extract an empty string. The result is the same with an empty string or and no data.
Any suggestion to handle this situation will be appreciated.
If you're using your parse
function exclusively for extraction, you can simply make it out to be a check for an empty buffer. If there is, simply clear
the string:
void parse(std::istream& is, std::string& out)
{
if (is.eof() || is.peek() == std::char_traits<char>::eof())
{
out.clear();
return;
}
is >> out;
}
There is no difference between an empty value and no value.
That's just your assumption, and it's not really true.
If you attempt to extract a string, it is expected that there are characters to extract. Before characters are available, it is impossible to perform any extraction, let alone one that results in extraction to a particular object.
This is entirely expected behaviour.
I guess your confusion stems from your prior check for argc > 1
, but although the shell pretended ./myProgram ""
had some argument, as far as your stream is concerned there is nothing in that argument.
If you wish to make your own handling for it, simply stick an if
condition on is.fail()
after the read.
#include <sstream>
#include <iostream>
int main(int argc, char** argv)
{
if (argc>1)
{
std::istringstream is(argv[1]);
std::string out;
is >> out;
if (is.fail()) {
std::cout << "Well, you gave me an argument, but it was empty, biatch!\n";
}
}
}
Don't bother checking is.eof()
; it'll be set when you reached the end of input whether it contained any characters or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With