假设单词之间以空格分隔:
unsigned int countWordsInString(std::string const& str)
{
std::stringstream stream(str);
return std::distance(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>());
}
注意:单词之间可能有多个空格。此外,这不会捕获其他空白字符,例如制表符换行符或回车符。所以计算空格是不够的。
流输入运算符 >> 用于从流中读取字符串。读取一个空格分隔的单词。所以他们可能正在找你用它来识别单词。
std::stringstream stream(str);
std::string oneWord;
stream >> oneWord; // Reads one space separated word.
什么时候可以使用它来计算字符串中的单词数。
std::stringstream stream(str);
std::string oneWord;
unsigned int count = 0;
while(stream >> oneWord) { ++count;}
// count now has the number of words in the string.
变得复杂:
流可以像任何其他容器一样对待,并且有迭代器可以循环它们 std::istream_iterator。当您在 istream_iterator 上使用 ++ 运算符时,它只是使用运算符 >> 从流中读取下一个值。在本例中,我们正在读取 std::string,因此它读取一个空格分隔的单词。
std::stringstream stream(str);
std::string oneWord;
unsigned int count = 0;
std::istream_iterator loop = std::istream_iterator<std::string>(stream);
std::istream_iterator end = std::istream_iterator<std::string>();
for(;loop != end; ++count, ++loop) { *loop; }
使用 std::distance 只是将上述所有内容包装在一个整洁的包中,因为它通过在第一个迭代器上执行 ++ 直到到达第二个迭代器来找到两个迭代器之间的距离。
为了避免复制字符串,我们可以偷偷摸摸:
unsigned int countWordsInString(std::string const& str)
{
std::stringstream stream;
// sneaky way to use the string as the buffer to avoid copy.
stream.rdbuf()->pubsetbuf (str.c_str(), str.length() );
return std::distance(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>());
}
注意:我们仍然将原始单词中的每个单词复制到临时单词中。但这样做的成本是最小的。