Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/25: Рейтинг темы: голосов - 25, средняя оценка - 4.64
 Аватар для moskitos80
442 / 99 / 42
Регистрация: 04.10.2011
Сообщений: 359

basic_istream::getline

23.07.2012, 01:36. Показов 4687. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем здравствуйте. Изучаю С++ по книге Р. Лафоре в главе 7 массивы и строки есть задание которое предполагает получение строки, содержащей пробелы в переменную типа string и тут при выполнении задания я столкнулся с непонятным поведением функции basic_istream::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
#include <iostream>
#include <string>
 
using namespace std;
 
const int SIZE = 100;
 
int main() {
    
    char ans;
    int numbers[SIZE];
    string empl[SIZE];
    
    for (int i = 0; i < SIZE; i++) {
        cout << "\nEnter number";
        cin >> empl[i];
        
        cout << "\nEnter name";
        getline(cin, empl[i]); // Вот этот момент программа как будто пропускает...
        
        cout << "\nEnter more data? y/n ";
        cin >> ans;
        
        if (ans == 'n') {
              break;
        }
    }
    
    cout << endl;      
    system("PAUSE");    
    
    return EXIT_SUCCESS;    
}
При выполнении программы происходит следующее:
прога пишет

Enter number - ввожу номер нажимаю enter

Далее прога выдает:

Enter name
Enter more data? y/n

Т.е. она не ждёт ввода после Enter name! Получается что getline(cin, empl[i]); как-то пропускается
Объясните пожалуйста чайнику с чем связано такое поведение? Использую Dev C++ 4.9.9.2
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.07.2012, 01:36
Ответы с готовыми решениями:

Cin.getline "error: no matching function for call to "STD::BASIC_istream<char> и.тд)
быстрый поиск в интернете дал понять, сущность проблемы, но не ее основу. касательно работы с интами все ОК. читает и выводит. с char он...

std::basic_istream<_CharT, _Traits>::basic_istream() [with _CharT = char; _Traits = std::char_traits<char>]» is protected
Есть класс: class Expression { public: Expression(string expr, ErrorCallback errcb=0); Expression(const Expression&amp; orig); ...

Отличие getline() от cin.getline()
Чем отличается getline() от cin.getline() ?

14
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 02:46
Лучший ответ Сообщение было отмечено как решение

Решение

После cin >> empl[i]; поставьте cin.get().

Добавлено через 8 минут
cin >> оставляет во входном потоке символ новой строки '\n'. Он становится первым считываемым символом для getline(). Для неё это пустая строка. Обрабатывает она её так: если пустая строка, то чтение останавливается, символ '\n' извлекается из очереди, но не сохраняется, в строку ввода помещается '\0'. Если после cin >> поставить cin.get(),то символ '\n' будет извлечён этим методом из потока, и дальше всё будет нормально.

Добавлено через 36 минут
И ещё, в 17 строке, наверное нужно cin >> numbers[i];?
5
 Аватар для xADMIRALx
70 / 64 / 5
Регистрация: 09.06.2012
Сообщений: 291
23.07.2012, 06:16
по мне так луче gets();
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.07.2012, 09:26
C++
1
2
3
4
5
6
cout << "\nEnter name";
 
cin.sinc();   // !!!
getline(cin, empl[i]);     
 
cout << "\nEnter more data? y/n ";
http://www.cplusplus.com/refer... ream/sync/
http://www.cplusplus.com/refer... am/ignore/
1
 Аватар для moskitos80
442 / 99 / 42
Регистрация: 04.10.2011
Сообщений: 359
23.07.2012, 10:18  [ТС]
alsav22 - благодарю за подробное пояснение.. По поводу 17 строки вы конечно правы, правда, в данном случае это не существенно, но всё же спасибо и за внимательность.
Avazart - спасибо за ссылки, я даже не знал про такой ресурс - очень пригодится!
xADMIRALx - учту на будущее
0
23.07.2012, 10:32

Не по теме:

Цитата Сообщение от xADMIRALx Посмотреть сообщение
по мне так луче gets();
вы документацию к этой функции читали? видимо нет
и вообще каким боком Си-шная функция в С++!?:-|

0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 21:19
Цитата Сообщение от Avazart Посмотреть сообщение
C++
1
2
3
4
5
6
cout << "\nEnter name";
 
cin.sinc();   // !!!
getline(cin, empl[i]);     
 
cout << "\nEnter more data? y/n ";
http://www.cplusplus.com/refer... ream/sync/
http://www.cplusplus.com/refer... am/ignore/
Несколько раз мне попадались рекомендации не использовать sinc(). Кажется, из-за непереносимости. Не знаю, насколько это обоснованно. Советуют ignore(). Вот ссылка, как это правильно делать: http://cppstudy.wordpress.com/... et-and-co/
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
23.07.2012, 21:28
Ну я не знаю как стандартная ф-ция может быть не переносимой, а на ignore() я ссылку тоже кинул.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2012, 05:17
Цитата Сообщение от Avazart Посмотреть сообщение
Ну я не знаю как стандартная ф-ция может быть не переносимой, а на ignore() я ссылку тоже кинул.
Вот ссылка на ту же тему, третий пост: Интересное поведение cin.getline(); Пишут, что
sync() можно, но это не сработает в linux
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
24.07.2012, 09:45
Да проврерил (в Ubuntu,g++) действительно не работает sinc(), а ignore() работает что странно по тому как назначение ф-ций, как я понимаю, тоже.
0
 Аватар для moskitos80
442 / 99 / 42
Регистрация: 04.10.2011
Сообщений: 359
24.07.2012, 10:59  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Да проврерил (в Ubuntu,g++) действительно не работает sinc(), а ignore() работает что странно по тому как назначение ф-ций, как я понимаю, тоже.
- Полезная инфа - спасибо.

alsav22 а этому товарищу: cppstudy.wordpress.com вообще зачёт!

Итог: принял для себя такое решение для подобных случаев - после чтения из буфера будем подчищать его таким макаром:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
 
using namespace std;
 
int main() {
    
    string name;
    int age;
    
    cout << "Enter age "; cin >> age;
 
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
        
    cout << "\nEnter name "; getline(cin, name);
    
    cout << "\nWas entered age " << age 
         << " name " << name << endl;
       
    system("PAUSE");    
    return EXIT_SUCCESS;    
}
Потому как такой способ (Dev 4.9.9.2 на Win 7x32) у меня не заработал:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <string>
 
using namespace std;
 
int main() {
    
    string name;
    int age;
    
    cout << "Enter age "; cin >> age;
    
    cin.ignore(cin.rdbuf()->in_avail(), '\n');
        
    cout << "\nEnter name "; getline(cin, name);
    
    cout << "\nWas entered age " << age 
         << " name " << name << endl;
       
    system("PAUSE");    
    return EXIT_SUCCESS;    
}
Единственное, для меня пока загадка - смысл этой строки (наверно здесь мы получаем какое то верхнее пороговое значение размера буфера, но вот способ получения... ) :

C++
1
numeric_limits<streamsize>::max()
Но это лишь потому, что до этого я пока ещё наверно не дочитал. А так спасибо ребята за разъяснения. Правда у меня ещё куча вопросов, но это уже другие темы
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,698
24.07.2012, 11:26
Итог: принял для себя такое решение для подобных случаев - после чтения из буфера будем подчищать его таким макаром:
...
C++
1
cin.ignore(numeric_limits<streamsize>::max(), '\n');


++++++++++++++++++++++++++++++++++++++++ ++++=

Определили для себя, что в буфере остался один символ (в нашем случае '\n'):
C++
1
2
3
        cout << "\nEnter name";
        getchar ();
        getline(cin, empl[i]);

Если необходимо очистить буфер консоли полностью и наверное, то так:
C++
1
2
3
        cout << "\nEnter name";
        fflush (stdin);
        getline(cin, empl[i]);
Всё!

++++++++++++++++++++++++++++++++++++++++ ++++=

Это Сишные функции, но кто нам запрещает использовать их в С++, имея ввиду, что С это подмножество C++?
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
24.07.2012, 11:45
kravam, по поводу fflush(stdin)
If it was open for reading and the last operation was an input operation, the behavior depends on the specific library implementation. In some implementations this causes the input buffer to be cleared, but this is not standard behavior.
ожидаемый эффект есть только под виндой в VS, про mingw не знаю
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2012, 20:46
Цитата Сообщение от moskitos80 Посмотреть сообщение
Единственное, для меня пока загадка - смысл этой строки
Цитата Сообщение от moskitos80 Посмотреть сообщение
numeric_limits<streamsize>::max()
Шаблонный класс numeric_limits. В данном случае, статический метод max(), выдаёт предельный размер для встроенного типа streamsize (размер потока), для данной платформы. Можно здесь почитать подробнее: http://www.cplusplus.com/refer... ic_limits/ В каких-то компиляторах, требуется: #include <limits>.

Добавлено через 9 минут
Цитата Сообщение от Jupiter Посмотреть сообщение
про mingw не знаю
Работает.
0
 Аватар для moskitos80
442 / 99 / 42
Регистрация: 04.10.2011
Сообщений: 359
24.07.2012, 23:31  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
Шаблонный класс numeric_limits. В данном случае, статический метод max(), выдаёт предельный размер для встроенного типа streamsize (размер потока), для данной платформы. Можно здесь почитать подробнее: http://www.cplusplus.com/refer... ic_limits/ В каких-то компиляторах, требуется: #include <limits>.
- Уф... до этого я ещё не дошёл, я дошёл пока только до перегрузки операторов и приведения пользовательских типов Тяжело конечно с PHP да Javascript переходить на языки с контролем типов да и вообще по сравнению с С++ они кажутся какими то игрушечными.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.07.2012, 23:31
Помогаю со студенческими работами здесь

Не найден оператор, принимающий левый операнд типа std::basic_istream
вот в этом коде в 120 строчке ошибка error C2678: бинарный &quot;!=&quot;: не найден оператор, принимающий левый операнд типа...

Объясните разницу между "cin.getline" и "std::getline"
string a; cin.getline(a); getline(cin, a);в чем разница между &quot;cin.getline(a);&quot; и &quot;getline(cin, a);&quot;

Getline() "съедает" следующий getline()
Всем привет! Пишу небольшое консольное приложение. Идея такова: в карточке пользователя библиотеки храниться информация о книгах. Вот...

error C2678: бинарный ">>": не найден оператор, принимающий левый операнд типа "std::basic_istream<_Elem,_Traits>"
Нужно из файла скачать информацию в объект. Почему у меня не получается? #include &lt;vector&gt; #include &lt;string&gt; #include...

Getline
Доброго времени суток. В чём ошибка? Пишет, что пространство имён &quot;std&quot; не содержит члена &quot;getline&quot;. while...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
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. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru