【问题标题】:Is it possible to accept from the user (standard input) to the string stream directly?是否可以直接从用户(标准输入)接受字符串流?
【发布时间】:2011-03-27 00:10:06
【问题描述】:

这是一个使用字符串流的示例程序。目标是接受来自用户的行(标准输入)并将每个单词打印在单独的行中。

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

我想知道,有没有办法,我可以避免中间字符串变量(对象),行并将用户输入直接存储到当前行(istringstream对象)。

注意:

我知道,下面的解决方案已经有了。

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

【问题讨论】:

  • 为什么不直接使用第二种解决方案?
  • 尼尔,这就是我打算做的。

标签: c++ stream io


【解决方案1】:

std::getline 需要一个字符串引用参数,这就是它放置它获得的行的位置,所以当然你不能避免传递这样一个参数(并且仍然使用那个函数)。如果您经常需要它,您可以优雅地封装该结构——例如:

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

【讨论】:

  • 不错的功能。但我相信,您打算将 istream 作为参数。在那种情况下,if语句不应该是这样的。 if ( std::getline(i,line) )
  • @Neil 和 @nsivakr,你们都说得对,tx -- +1,编辑修复。
【解决方案2】:

我假设您不想使用中间对象来防止不必要的复制?

您可以通过显式设置流缓冲区缓冲区来实现相同的效果。

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

因为毁灭的顺序。您只需要确保 istringstream 在您用作缓冲区的对象之前被销毁。因此,您需要重新安排 main() 顶部的声明,以确保首先创建该行并因此将最后销毁(否则 istringstream 的析构函数有可能访问已释放对象的内存.

【讨论】:

  • 喜欢这个解决方案。但是当我运行程序时,它不会打印这些单词。换句话说,内部的 while 循环每次都会失败。
  • @nsivakr:已修复。仅仅因为您重置缓冲区并不意味着标志被重置。添加回调用 clear 以重置标志。
【解决方案3】:

如果你想简化第一个解决方案,

while ( currentline(line) >> eachword )

【讨论】:

  • Jacob,当我尝试时,它甚至没有编译。
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 2010-10-04
  • 1970-01-01
  • 2015-07-30
  • 2011-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多