开发者

Is it possible to accept from the user (standard input) to the string stream directly?

Here is a sample program that uses stringstream. The goal is to accept lines from the user(standard input) and print each word in a separate line.

int main()
{

    std::istringstream currentline;
    std::string eachword;
    std::string line;

    // Accept line from the standard input till EOF is reached
    while ( std::getline(std::cin,line) )
    {
        currentline.str(line); // Convert the input to stringstream
        while ( currentline >> eachword ) // Convert from the entire line to individual word
        {
            std::cout << eachword << std::endl;
        }
        currentline.clear();
    }
    return 0;
}

I'm wondering, is there a way , I can avoid the intermediate string variable(object), line and di开发者_JS百科rectly store the user input to the currentline (istringstream object).

Note:

I know, the following solution already.

while ( std::cin >> eachword)
{
    std::cout << eachword << std::endl;
}


std::getline needs a string reference argument, and that's where it places the line it has obtained, so of course you can't avoid passing such an argument (and still use that function). You could elegantly encapsulate the construct, if you need it often -- e.g.:

bool getline(std::istream& i, std::istringstream& current)
{
    std::string line;
    if ( std::getline(i, line) ) {
        current.str(line);
        return true;
    }
    return false;
}


If you want to simplify the first solution,

while ( currentline(line) >> eachword )


I assume you want to not use an intermediate object to prevent unnecessary copying?

You can achieve the same affect by explicitly setting the stream buffers buffer area.

int main()
{
    std::string line;
    std::istringstream currentline;
    std::string eachword;

    // Accept line from the standard input till EOF is reached
    while ( std::getline(std::cin,line) )
    {
        // Set the buffer without copying.
        currentline.clear();
        currentline.rdbuf()->pubsetbuf(&line[0], line.length() );

        while ( currentline >> eachword )
        {
            std::cout << eachword << std::endl;
        }
    }
    return 0;
}

Because of the order of destruction. You just need to make sure the istringstream is destroyed before the object you are using as a buffer. So you need to re-arrange the declarations at the top of main() to make sure that line is created first and thus will be destroyed last (otherwise the destructor of the istringstream has the potential for accessing the memory of a free'ed object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜