Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
Роман К.
3 / 3 / 0
Регистрация: 08.11.2010
Сообщений: 6
#1

"Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? - C++

21.03.2011, 17:11. Просмотров 1980. Ответов 7
Метки нет (Все метки)

Итак... Имеется кусок кода, который должен принимать с клавиатуры порядковый номер работы (целое число), её название (строка) и описание (опять-таки, строка). Учитывая, что "название" и "описание" будут содержать в себе знаки препинания, решил использовать getline().

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
#include <iostream>
#include <stdio.h>
#include <string>
 
using namespace std;
 
 
int nrabota;
string s1 = " название";
string s2 = " описание";
 
 
int main()
{
    cout << "Hello world!" << endl;
 
 
//Начало целочисленного ввода
    cout << "\n\nУказываем порядковый номер работы \n";   //Порядковый номер работы
    cin >> nrabota; //Порядковый номер работы, присваиваем значение переменной
    cout << "Вы ввели номер работы " << nrabota << "\n\n";    //Результат для проверки, потом выпиливаем
//Конец целочисленного ввода
 
 
//Начало строкового ввода
    cout << "Вводим название работы\n";
    getline(cin, s1);
    cout << "Вы ввели\t" << s1 << "\n";
 
    cout << "\nВводим описание\n";
    getline(cin, s2);
    cout << "Вы ввели\t" << s2 << "\n";
//Конец строкового ввода
 
    cout << nrabota << ". " << "[b]" << s1 << "[/b] " << "\n" << s2 << "\n";    //Вывод результата
 
 
    return 0;
}
Казалось бы, всё нормально и ошибиться негде, но при выполнении возникает досадный глюк. getline(), следующий за целочисленным вводом, "проскакивает": то есть, курсор не останавливается, и программа ввода с клавиатуры не ждёт. Переменная при этом принимает значение "пустоты" - умолчание, заданное при объявлении, стирается. Второй getline(), который "описание", в данном случае, работает нормально.

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

Теоретически, идеи "костылей" очевидны: можно всобачить между целочисленным и строковым вводом ещё один, заведомо ненужный, строковой ввод, который и будет зануляться; можно попробовать вывести строковые вводы в отдельную функцию (не пробовал, но, насколько я понимаю ситуацию, может помочь). Однако,

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


P.S. Прошу прощения, если ответ уже где-то существует на этом форуме. Я не смог придумать, как сформулировать адекватный поисковый запрос для моей проблемы.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.03.2011, 17:11     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему?
Посмотрите здесь:
Объясните разницу между "cin.getline" и "std::getline" C++
C++ Почему переменная "d" не была удалена из стека после выхода из функции?
Почему в выводе выдаются предупреждения "warning C4101: sm: неиспользованная локальная переменная" C++
Вывести решения уравнения, если их число конечно, "NO", если решений нет, и "INF", если их бесконечно много C++
"Проскакивает" выбор пункта меню C++
Проскакивает getline C++
C++ Если переход строки обозначается " \r\n" почему символ '\r' не считывается, а только '\n'(10), и что делать?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IrineK
Заблокирован
21.03.2011, 17:20     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #2
Попробуйте:
C++
1
cin.sync();
Убирает мусор из потока ввода.

http://www.cplusplus.com/reference/i.../istream/sync/
Роман К.
3 / 3 / 0
Регистрация: 08.11.2010
Сообщений: 6
21.03.2011, 18:09  [ТС]     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #3
Цитата Сообщение от IrineK Посмотреть сообщение
Попробуйте:
C++
1
cin.sync();
Убирает мусор из потока ввода.

http://www.cplusplus.com/reference/i.../istream/sync/
Признаться, я не понял, как приведённая Вами функция должна работать, но попробовал. Вставил соответствующую строчку за вводом номера:

C++
1
2
3
4
5
6
//Начало целочисленного ввода
    cout << "\n\nУказываем порядковый номер работы \n";   //Порядковый номер работы
    cin >> nrabota; //Порядковый номер работы, присваиваем значение переменной
    cin.sync(); //Чистим cin по форумному совету
    cout << "Вы ввели номер работы " << nrabota << "\n\n";    //Результат для проверки, потом выпиливаем
//Конец целочисленного ввода
Результата, нет... Всё то же "проскакивание"... Вы не могли бы пояснить, как нужно использовать эту функцию? Или она работает только в паре с cin.get (если так, то мне, всё-таки, хотелось бы с getline() разобраться)?
_Medved
3 / 3 / 1
Регистрация: 21.03.2011
Сообщений: 3
21.03.2011, 18:30     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #4
Думаю тебе поможет функция cin.ignore(); после использования cin >> nrabota;

Добавлено через 13 минут
После ввода переменной в "nrabota", по нажатию клавиши "Enter", в буфер попадает символ '\n' - конец строки, а для функции getline() по умолчанию именно символ '\n' означает конец ввода. Поэтому при первом употреблении функции getline() курсор проскакивает, так как думает, что ввод был завершен.
Поправьте меня, если я что-то неправильно сказал. Я тоже только учусь ещё.
IrineK
Заблокирован
21.03.2011, 18:41     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #5
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
#include <iostream>
#include <stdio.h>
#include <string>
 
using namespace std;
 
 
int nrabota;
string s1 = " название";
string s2= " описание";
 
 
int main()
{
    cout << "Hello world!" << endl;
 
 
//Начало целочисленного ввода
    cout << "\n\nУказываем порядковый номер работы \n";   //Порядковый номер работы
    cin >> nrabota; //Порядковый номер работы, присваиваем значение переменной
    cout << "Вы ввели номер работы " << nrabota << "\n\n";    //Результат для проверки, потом выпиливаем
//Конец целочисленного ввода
 
 
//Начало строкового ввода
    cout << "Вводим название работы\n";
    cin.sync();
    getline(cin, s1);
    cout << "Вы ввели\t" << s1 << "\n";
 
    cout << "\nВводим описание\n";
    cin.sync();
    getline(cin, s2);
    cout << "Вы ввели\t" << s2 << "\n";
//Конец строкового ввода
 
    cout << nrabota << ". " << "[b]" << s1 << "[/b] " << "\n" << s2 << "\n";    //Вывод результата
 
 
    return 0;
}
Роман К.
3 / 3 / 0
Регистрация: 08.11.2010
Сообщений: 6
21.03.2011, 19:20  [ТС]     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #6
_Medved, Угу... Огромное спасибо. Вариант с cin.ignore(); помог.

По поводу лишнего \n: я тоже как-то так ситуацию понимаю. Только шутка в том, что он там не всегда оказывается, а именно на стыке "нестроки" со строкой. Ну да ладно...

IrineK, А cin.sync(); , всё равно, почему-то не помогает (хотя компилируется, но к эффекту не приводит).
IrineK
Заблокирован
21.03.2011, 19:24     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #7
Предложенный мною вариант также работает.
Ну, возможно не у всех..
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.03.2011, 19:29     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему?
Еще ссылки по теме:
Странное поведение при работе со строками: почему программа выводит 8, если в input "МАКС"? C++
C++ Для каждого элемента последовательности вывести на экран "true" если число чётное и "false" если число нечёное
C++ Почему если во вторую и третью строку, вводить сперва символы а потом числа. То atoi, atof выводят "0"
Подскажите почему может появляться ошибка: "неразрешенный внешний символ "_SDL_..."" C++
C++ Даны две строки. Если они начинаются с одинаковых символов, то напечатать "ДА", иначе - "НЕТ"

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

Или воспользуйтесь поиском по форуму:
Роман К.
3 / 3 / 0
Регистрация: 08.11.2010
Сообщений: 6
21.03.2011, 19:29  [ТС]     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #8
IrineK, в любом случае, спасибо за ответ...
Yandex
Объявления
21.03.2011, 19:29     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru