处理空字符串case从std :: istream中提取字符串

时间:2014-01-04 01:49:41

标签: c++ stl

使用以下代码从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;
    }
}

使用非空字符串,输出如下:

$./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

使用空字符串,输出如下:

$./a.out ""
good:1 fail:0 eof:0 in_avail:0 value:__INIT__
good:0 fail:1 eof:1 in_avail:0 value:__INIT__

而不是这个,我希望:

good:1 fail:0 eof:0 in_avail:0 value:__INIT__
good:0 fail:0 eof:1 in_avail:0 value:

运营商&gt;&gt;不提取空字符串。结果与空字符串相同或没有数据。

任何有关处理这种情况的建议都将受到赞赏。

2 个答案:

答案 0 :(得分:2)

  

空值与无值之间没有区别。

这只是你的假设,并不是真的。

如果您尝试提取字符串,则需要提取字符。在字符可用之前,不可能执行任何提取,更不用说提取到特定对象的提取。

这是完全预期的行为。

我猜您的混淆源于您先前检查argc > 1,但是虽然shell假装./myProgram ""有一些参数,但就您的流而言时,该参数中没有任何内容< / em>的

如果您希望自行处理,请在阅读后在if上粘贴is.fail()条件。

#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";
        }
    }
}

不要费心检查is.eof();当你到达输入结尾时它是否会被设置,无论它是否包含任何字符。

答案 1 :(得分:2)

如果您专门使用parse函数进行提取,则可以简单地将其作为空缓冲区的检查。如果有,只需clear字符串:

void parse(std::istream& is, std::string& out)
{
    if (is.eof() || is.peek() == std::char_traits<char>::eof())
    {
        out.clear();
        return;
    }

    is >> out;
}