При условии, что слова разделены пробелами:
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>());
}
Примечание: мы все равно копируем каждое слово из оригинала ввременный характер.Но стоимость этого минимальна.