Способы завершить предложение в С++?

Я новичок в Cpp и пытаюсь просмотреть примеры, приведенные в книге «Принципы и практика программирования с использованием С++» (2-е издание).

Для дальнейшего справки я говорю о «4.6.4 Текстовый пример», где предложение нужно взять в качестве входных данных и построить словарь слов (после сортировки).

Пример, который был упомянут, был похож на приведенный ниже.

// simple dictionary: list of sorted words
int main()
{
  vector<string> words;
  for(string temp; cin>>temp; ) // read whitespace-separated words
     words.push_back(temp); // put into vector
  cout << "Number of words: " << words.size() << '\n';
  sort(words); // sort the words
  for (int i = 0; i<words.size(); ++i)
     if (i==0 || words[i–1]!=words[i]) // is this a new word?
        cout << words[i] << "\n";
}

В приведенном выше образце кода строка номер 5 (в выражении цикла for) cin >> temp не имеет для меня смысла. Почему? После запуска кода появилась консоль, и я начал вводить предложение с парой слов, и даже после нажатия ввода я не смог завершить строку и перейти к следующей строке? Как завершить ввод здесь?

Не по теме, но -- if (i==0 || words[i–1]!=words[i]) не будет работать для чего-то вроде apple banana apple banana. Самое простое решение — использовать std::set<std::string>, так как он не только сортирует, но и хранит только уникальные элементы.

PaulMcKenzie 05.04.2023 18:55

В настоящее время поток не может прочитать, чтобы выйти из цикла. При чтении в std::string это довольно сложно сделать без закрытия входного потока. В зависимости от используемого программного обеспечения терминала это можно сделать с помощью CTRL+D xили CTRL+Z на большинстве настольных платформ. Обратите внимание, что после закрытия может быть трудно снова открыть cin.

user4581301 05.04.2023 18:55

Обычно я делаю что-то вроде варианта 2 в этом связанном ответе. Прочитайте всю строку из входного потока, запишите эту строку во второй поток. Прокрутите второй поток. В конце строки второй поток заканчивается, выходя из цикла.

user4581301 05.04.2023 18:57

@PaulMcKenzie: ты пропустил sort(words);.

Jarod42 05.04.2023 18:58

Альтернативой может быть труба: cat some_file | your_app

Jarod42 05.04.2023 19:00

@ Jarod42 Да, я пропустил это. Тем не менее, использование std::set<std::string> устранит необходимость в sort() или последующем цикле for.

PaulMcKenzie 05.04.2023 19:06

Незначительная опасность: в words[i–1] не является знаком минус.

user4581301 05.04.2023 19:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
121
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

cin >> temp не имел для меня смысла. Почему?

  for(string temp; cin>>temp; ) // read whitespace-separated words
     words.push_back(temp); // put into vector

Это эквивалентно:

string temp;
while (cin >> temp)
{
    words.push_back(temp);
}

cin>>temp будет оцениваться как false, когда будет достигнут конец входного потока, и вызовет разрыв цикла. В противном случае temp присваивается строка, а cin>>temp оценивается как истина.

информация OP отсутствует: Что такое входной поток? Что им нужно для входа?

463035818_is_not_a_number 05.04.2023 19:00

Если это перенаправленный файл из командной строки, то ничего. Если это из консоли, то я полагаю, что это CTRL+Z в Windows и CTRL+D в Unix/Mac.

selbie 06.04.2023 08:31

Оператор >> — это перегруженная функция.

Что на самом деле называется operator>>(cin, temp).

Функция возвращает сам поток (cin), который имеет перегруженный оператор преобразования bool, который возвращает true, если состояние потока в порядке. Он возвращает false в случае ошибки, например, в конце файла.

Это означает, что поток и операторы ввода могут использоваться как часть логического условия для чтения до тех пор, пока вы не достигнете конца файла.

тот же комментарий здесь: отсутствует информация OP: что такое конец файла, когда они печатают на консоли? Что вводить?

463035818_is_not_a_number 05.04.2023 19:01

@ 463035818_is_not_a_number: Этот пример скопирован (ничего не изменилось), и автор (изобретатель С++) попытался объяснить, что происходит после выполнения примера. В книге каким-то образом он был завершен, но когда я пробую тот же код, это не так.

V B 05.04.2023 19:46

cin >> temp будет оцениваться как false, если операция ввода завершится неудачно. Наиболее распространенная ошибка при чтении в string — это достижение конца файла, и это условие, которое вы хотите вызвать.

В большинстве оболочек Linux (или других POSIX) маркер конца файла можно ввести, нажав ctrl+d. В хосте консоли Windows это ctrl+x.

В качестве альтернативы, вместо непосредственного взаимодействия с программой, вы можете связать ее ввод с выводом какой-либо другой команды с помощью конвейера. Когда команда, генерирующая вывод, завершается и закрывает свой конец канала, ваша программа увидит условие конца файла. Например, что-то вроде этого будет работать практически на любой оболочке:

echo "this is some text" | your-program

Или, используя большинство современных оболочек POSIX, вы можете использовать файл heredoc. Это работает в основном так же, как и выше, но сама оболочка записывает во входной поток вашей программы вместо того, чтобы подключать для этого внешнюю команду:

your-program <<EOF
this is some text
EOF

Я сохраню этот ответ, он может быть полезен в будущем. Спасибо.

V B 05.04.2023 19:52
Ответ принят как подходящий

Поскольку программа в настоящее время написана, поток не может быть прочитан, чтобы выйти из цикла. При чтении в std::string это довольно сложно сделать, string с радостью съест что угодно, не закрывая входной поток. В зависимости от используемого программного обеспечения терминала закрытие потока можно выполнить с помощью CTRL+D x или CTRL+Z на большинстве настольных платформ.

Обратите внимание, что после закрытия может быть трудно снова открыть cin, поэтому обычно я делаю что-то вроде варианта 2 в этом связанном ответе. Прочитайте всю строку из входного потока, запишите эту строку во второй поток. Прокрутите второй поток. В конце строки второй поток заканчивается, выходя из цикла.

Тривиальная многострочная версия исходного кода может выглядеть так:

int main()
{
    std::string line;
    while (std::getline(cin, line))
    {
        std::istringstream iss(line); // #include <sstream>
        vector<string> words;
        for(string temp; iss>>temp; ) // read whitespace-separated words
            words.push_back(temp); // put into vector

        cout << "Number of words: " << words.size() << '\n';
        sort(words); // sort the words
        for (int i = 0; i<words.size(); ++i)
            if (i==0 || words[i-1]!=words[i]) // is this a new word?
                cout << words[i] << "\n";
    }
}

Это сработало, хотя использовались некоторые дополнительные темы, такие как потоки строк, но я понял, что пример, упомянутый в книге на данный момент, не может завершить строку без дополнительной помощи, такой как код, который вы упомянули.

V B 05.04.2023 19:50

Другие вопросы по теме