Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

C++. Подсчёт слов в строке

PeridotChan;) Профи (571), на голосовании 4 года назад
Пользователь вводит предложение. Нужно посчитать, сколько в нём слов. В третьем слове нужно посчитать количество букв "а".

Как-то у меня тупик возник...

#include iostream
#include string
#include Windows.h
#include cctype
using namespace std;

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int count = 0;
string Line;
cout << "Введите предложение: ";
getline(cin, Line);
for (int i = 0; i < Line.size(); i++)
{
if (isspace(i))
count++;
}
cout << "Слов в предложении - " << count;
}

Писал следующее:
Мама - 0 слов
Мама мыла - 0 слов
Мама мыла раму - 5 слов.
Голосование за лучший ответ
Peer-2-Peer Мудрец (16178) 4 года назад
  Простите, конечно же, Автор, но алгоритм Вашей программы делает не то, что требуется.

  Лично я бы предложил не считать пробелы, поскольку таким образом не учитываются пробелы, идущие подряд, предложения, состоящие только из пробелов, предложения не содержащие пробелов.

  ИМХО, простите, если не понравится, лучше считывать слово за словом, например, перегруженной в потоке операцией сдвига (то есть cin >> ). Эта операция как раз воспринимает пробелы как разделители вводимых строк, а несколько пробелов подряд считает одним разделителем.

  Полезный метод потоков ввода (а значит и cin) — peek(). Его можно вызывать всякий раз перед тем, как считать с клавиатуры очередное слово. Позволяет проверить, закончен ли ввод, определяя код следующего символа на очереди к считыванию из потока, но фактически не считывает его. Следовательно, если на очереди к считыванию символ '\n' либо EOF, значит, ввод фактически закончен, и любая попытка ввести следующее слово приведёт к ожиданию ввода с клавиатуры.

    ПРИМЕРНАЯ ПРОГРАММА:

#include <iostream>
#include <string>

using namespace std;

int main()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
int count = 0;
string Line;
cout << "Введите предложение: \n";
// подготовка к вводу с клавиатуры
cin.clear();
cin.sync();
while ('\n' != cin.peek()) // цикл пока не нажата клавиша Enter
{
if (!(cin >> Line)) break; // выход, если встретился конец потока
count++; // считано ещё одно слово — увеличиваем счётчик
}
cout << "Слов в предложении - " << count;
}
Peer-2-PeerМудрец (16178) 4 года назад
А внутри цикла после строки count++ можно проверить, является ли слово третьим по счёту, и сохранить копию этого слова для последующего подсчёта количества букв 'а' в этом слове.
...Гений (84901) 4 года назад
+1 И автору вопроса - Ваш основной косяк в коде здесь
if (isspace(i))
а должно было быть
if (isspace(Line[i]))

Но всё равно как выше заметили не решит проблему повторяющихся пробелов. Более того слова могут быть разделены табуляцией. Если в условии сказано что пробел между словами ровно один - не вопрос.
... Гений (84901) ...,Да isspace проверяет и на табуляцию. Я неудачно выразился - хотел сказать что могут быть пробел и табуляция н-р.
Peer-2-PeerМудрец (16178) 4 года назад
  Возможен вариант программы с классом istringstream. Этот класс требует подключения библиотеки stringstream:

#include <stringstream>

  Удобно, что в классе istringstream не возникает состояние ожидания ввода, впику классу istream, которому принадлежит объект cin. По окончании входной строки возникает EOF. При попытке чтения после EOF происходит повреждение потока, а значение переменной не меняется.

  В этом случае ввод с клавиатуры производится функцией getline() вплоть до конца строки.

  Далее объявляется объект класса istringstream (для примера назовём его iss) с инициализацией в скобках:

getline(cin, Line);
istringstream iss(Line);

  Далее очень простой цикл while, как то:

while(iss >> St) count++; // переменная St тоже типа string
Peer-2-Peer Мудрец (16178)   Выражение iss >> St не только обеспечивает выбор каждого слова из потока, но и отвечает за повреждение потока. Внутри if или while значение такого выражения преобразуется к типу bool; значение False означает, что поток повреждён.
Похожие вопросы