С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 Аватар для rim41
1045 / 313 / 78
Регистрация: 16.03.2020
Сообщений: 954

Использование cin.ignore в цикле while

23.10.2022, 10:38. Показов 343. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
//#include "CodeDecode.hpp"
 
int getmode(int mode)
{
    std::cout << "Write 1 for code, write 2 for decode, write -1 for exit:" << std::endl;
    std::cin >> mode;
    std::cin.ignore(); // необходимо для корректной работы getline
    return mode;
}
 
int main()
{
    int mode = 0;
 
    while (true) {
        std::string str;
 
        mode = getmode(mode);
        if (mode == 0) {
            std::cout << "Wrong mode (string not int), try again" << std::endl;
            mode = getmode(mode);
            continue;
        }
        else if (mode == -1) {
            std::cout << "Bye user!";
            break;
        }
        else if (mode == 1) {
            std::cout << "Text for code:" << std::endl;
            getline(std::cin, str);
            std::cout << "Coded text: " << std::endl << str << std::endl;
        }
        else if (mode == 2) {
            std::cout << "Text for decode:" << std::endl;
            getline(std::cin, str);
            std::cout << "Decoded text:" << std::endl << str << std::endl;
        }
        else {
            std::cout << "Wrong mode (bad int), try again" << std::endl;
            mode = getmode(mode);
            continue;
        }
    }
    return 0;
}
}
в случае передачи в переменную mode букв вместо цифры в неё попадает значение 0, я это проверяю первым ифом, но создаётся вечный цикл, почему так? Причем казалось бы такая же конструкция в else работает абсолютно правильно
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.10.2022, 10:38
Ответы с готовыми решениями:

Как работает cin.peek, cin,get, cin.ignore, cin.clear?
Здравствуйте, товарищи и не товарищи!:) Я только начал изучать C++, а уже использую вещи, которые мне не понятны, и прошу объяснить, как...

Метод getline(cin, m) не срабатывает без cin.ignore() / Ревью кода
Почему в моем случае getline(cin, m) не срабатывает без cin.ignore() ? Если по коду есть какие-нибудь замечания, то просьба написать что не...

Объясните работу методов cin.getline и cin.ignore
Фрагмент программы ниже. Что делают cin.getline и cin.ignore (12-13 строки) void WorkWithBooks(int Books) { if (Books &gt; 0) ...

6
 Аватар для Nishen
1357 / 856 / 365
Регистрация: 26.02.2015
Сообщений: 3,814
23.10.2022, 10:41
Распространенные ошибки
0
 Аватар для rim41
1045 / 313 / 78
Регистрация: 16.03.2020
Сообщений: 954
23.10.2022, 10:45  [ТС]
Nishen, уже смотрел это, возможно я туплю, но не могу всё равно понять как конкретную проблему исправить
0
 Аватар для ram876
759 / 456 / 213
Регистрация: 19.12.2016
Сообщений: 1,815
23.10.2022, 11:35
Лучший ответ Сообщение было отмечено rim41 как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
//#include "CodeDecode.hpp"
 
int getmode()
{
    int mode;
    std::cout << "Write 1 for code, write 2 for decode, write -1 for exit:" << std::endl;
    std::cin >> mode;
    std::cin.get();// необходимо для корректной работы getline
    return mode;
}
 
int main()
{
    int mode = 0;
    
    while (true) {
        std::string str;
 
        mode = getmode();
        if (!std::cin) {
            std::cin.clear();
            while(std::cin.get() != '\n');
            std::cout << "Wrong mode (string not int), try again" << std::endl;
            mode = getmode();
            continue;
        }
        else if (mode == -1) {
            std::cout << "Bye user!";
            break;
        }
        else if (mode == 1) {
            std::cout << "Text for code:" << std::endl;
            getline(std::cin, str);
            std::cout << "Coded text: " << std::endl << str << std::endl;
        }
        else if (mode == 2) {
            std::cout << "Text for decode:" << std::endl;
            getline(std::cin, str);
            std::cout << "Decoded text:" << std::endl << str << std::endl;
        }
        else {
            std::cout << "Wrong mode (bad int), try again" << std::endl;
            mode = getmode();
        }
    }
    return 0;
}
Добавлено через 28 секунд
Я весь код не смотрел, лишь подправил начало.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12930 / 6798 / 1820
Регистрация: 18.10.2014
Сообщений: 17,205
23.10.2022, 12:02
Цитата Сообщение от rim41 Посмотреть сообщение
создаётся вечный цикл
Не создается. Код невозможно даже скомпилировать из-за отсутствия #include <string>.

Цитата Сообщение от rim41 Посмотреть сообщение
в случае передачи в переменную mode букв вместо цифры в неё попадает значение 0
Нет, не попадает никакого значения 0. Откуда вы такое взяли? Значение mode остается нетронутым, то есть сохраняется то значение, которое был в переменной mode изначально.

Отдельный вопрос: а зачем вы тогда вообще передаете параметр mode в функцию getmode?

Цитата Сообщение от rim41 Посмотреть сообщение
я это проверяю первым ифом
Так "проверять" это бесполезно. См. выше.

Цитата Сообщение от rim41 Посмотреть сообщение
но создаётся вечный цикл
Ну так ваш поток переходит в ошибочное состояние, в котором он вообще ничего не делает. Вот и получается бесконечный цикл. Сначала надо вывести его из этого ошибочно стояния вызовом std::cin.clear().

Также, ваш ignore() игнорирует один символ. То есть даже с std::cin.clear(), если пользователь по ошибке введет 10 букв, то вы будете делать 10 итераций, чтобы эти буквы по одной вычистить из потока. Почему вы игнорируете символы по одному, а не сразу все?

Добавлено через 9 минут
Цитата Сообщение от ram876 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
    while (true) {
        std::string str;
        mode = getmode();
        if (!std::cin) {
            std::cin.clear();
            while(std::cin.get() != '\n');
            std::cout << "Wrong mode (string not int), try again" << std::endl;
            mode = getmode();
            continue;
        }
        ...
Что это такое? Зачем делается вызов getmode() за которым после continue снова вызовется getmode()?
1
 Аватар для ram876
759 / 456 / 213
Регистрация: 19.12.2016
Сообщений: 1,815
23.10.2022, 12:18
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Что это такое?
Я уточнял
Цитата Сообщение от ram876 Посмотреть сообщение
Я весь код не смотрел, лишь подправил начало.
0
 Аватар для rim41
1045 / 313 / 78
Регистрация: 16.03.2020
Сообщений: 954
23.10.2022, 12:33  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Не создается. Код невозможно даже скомпилировать из-за отсутствия #include <string>.
в закомментируемом подключении есть это, не учел когда комментировал что могу ввести в заблуждение подобным образом
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
надо вывести его из этого ошибочно стояния вызовом std::cin.clear().
прошу меня простить, я жертва многочисленных курсов на которых некоторые базовые вещи даются очень поверхностно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
23.10.2022, 12:33
Помогаю со студенческими работами здесь

Для чего в код вводится cin.ignore после того, как cin>> уже сработало?
Доброго времени суток! Просматриваю простой код. Вводится строка типа string: фунты и дюймы Затем значения переводится в типы int и...

Проблема с cin.ignore() и cin.clear()
Есть проблема. Добавлено через 11 минут // ConsoleApplication6.cpp: определяет точку входа для консольного приложения. // ...

Cin.clear cin.ignore
Как использовать cin.clear и cin.ignore?

cin.getline и cin.ignore
Есть кусок кода в котором не могу разобраться. Если cin.ignore() есть, то теряется первый вводимый символ начиная со второго входа в for....

cin.ignore
Как работает эта функция? cin.ignore (1, '#');


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru