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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
Роман К.
3 / 3 / 0
Регистрация: 08.11.2010
Сообщений: 6
21.03.2011, 17:11     "Проскакивает" getline(), если ранее вводилась целочисленная переменная. Почему? #1
Итак... Имеется кусок кода, который должен принимать с клавиатуры порядковый номер работы (целое число), её название (строка) и описание (опять-таки, строка). Учитывая, что "название" и "описание" будут содержать в себе знаки препинания, решил использовать 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(), если ранее вводилась целочисленная переменная. Почему?
Посмотрите здесь:

C++ дано четырехзначное число. если сумма первых 2 цифр=сумме 2 последних, написать "yes", иначе "no"
Мой компилятор не принимает "getline" и не хочет массив объявлять peson p[a] C++
Подскажите почему может появляться ошибка: "неразрешенный внешний символ "_SDL_..."" C++
C++ если не составит труда(при вводе "n" должно создаваться предложение "Мне n год (года)")
C++ Даны две строки. Если они начинаются с одинаковых символов, то напечатать "ДА", иначе - "НЕТ"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
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(), если ранее вводилась целочисленная переменная. Почему?
Еще ссылки по теме:

Что делает цикл "while(cin.getline(buf,l_buf))" ? C++
C++ Почему переменная "d" не была удалена из стека после выхода из функции?
"Проскакивает" выбор пункта меню C++

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

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

Текущее время: 03:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru