#c
#c #циклы #для цикла #структура
Вопрос:
Всем привет, я выполняю задание по программированию для структурированных данных, и я полагаю, что понимаю, как работают структуры.
Я пытаюсь прочитать в списке имена учащихся, идентификационные номера (A-Numbers) и их балансы.
Однако, когда я компилирую свой код, он будет считывать все в первый раз, но во второй раз по циклу и каждый раз после, он запрашивает имя пользователя, но пропускает getline и переходит прямо к записи A-Number и A-number.
Любая помощь была бы оценена. Просто пытаюсь выяснить, как заставить getline работать каждый раз, когда цикл выполняется.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main(){
const int maxStudents = 30;
struct Students{
string studentName;
int aNumber;
double outstandingBalance;};
Students students[maxStudents];
for(int count = 0; count < maxStudents-1; count )
{
cout<<"Student Name:";
cin.ignore();
getline(cin,students[count].studentName);
cout<<"nA-Number:";
cin>>students[count].aNumber;
if(students[count].aNumber == -999)
break;
cout<<"nOutstanding Balance:";
cin>>students[count].outstandingBalance;
}
cout<<setw(20)<<"A-Number"<<"Name"<<"Balance";
for(int count2 = 29; count2 >= maxStudents-1; count2--)
cout<<setw(20)<<students[count2].aNumber<<students[count2].studentName<<students[count2].outstandingBalance;
system("pause");
return 0;
}
Комментарии:
1. разве вы не можете просто использовать
cin>>students[count].studentName;
. Это работает, кстати2. @Neox — нет, если в имени учащегося есть пробел, как в имени Джона Хэнкока.
Ответ №1:
Посмотрите часто задаваемые вопросы по C в iostreams.
Пункт 15.6 конкретно касается вашей проблемы («Почему моя программа игнорирует мой запрос на ввод после первой итерации?»), Но вы можете найти полезной всю страницу.
HTH,
Ответ №2:
Поместить
cin.ignore();
в конце цикла.
Ответ №3:
Причина, по которой то, что вы делаете, не работает, заключается в том, что операторы ‘>>’ в первый раз не извлекают конечную строку 'n'
, следующая getline
видит ее и немедленно возвращает с пустой строкой.
Простой ответ: не смешивайте getline
и >>
. Если ввод ориентирован на строку, используйте getline
. Если вам нужно проанализировать данные в строке с помощью >>
, используйте строку, прочитанную getline
для инициализации std::istringstream
, и используйте >>
для нее.
Комментарии:
1. Я понимаю, что я сделал не так, но остальная часть вашего ответа оставила меня в полном замешательстве относительно того, что вы пытаетесь сказать мне делать.
2. Я использовал cin.ignore(); перед getline, чтобы решить мою проблему.
3. @sircrisp: создайте строку
std::istringstream
изstd::string
, содержащую прочитанную строку. Затем вы можете извлекать разделенные пробелом элементы из потока так же, как вы делаете сstd::cin
:istr >> item;
4. Приятно! Спасибо за совет. Не могу использовать его для этой конкретной программы, хотя из-за требований к домашней работе. Должна быть строка.
5. Также: проверяйте состояние потока после каждого ввода. Ваш код будет вести себя очень забавно, если кто-то вводит
"abc"
, когда он должен ввести число. (На самом деле, это главное преимуществоgetline
/istringstream
подхода. Ошибка в таких случаях будет наistringstream
, который является локальным для цикла. И независимо от того, что происходит, основной ввод остается синхронизированным в строках.)
Ответ №4:
Проблема заключается в смешивании cin
и getline
. Форматированный ввод (с помощью оператора >>) и неформатированный ввод (например, getline) плохо сочетаются друг с другом. Вам определенно следует прочитать об этом больше. Нажмите здесь для получения дополнительных пояснений.
Вот решение вашей проблемы. cin.ignore(1024, 'n');
это ключ.
for(int count = 0; count < maxStudents-1; count )
{
...
cout<<"nOutstanding Balance:";
cin>>students[count].outstandingBalance;
cin.ignore(1024, 'n');
}
Ответ №5:
Если у вас возникли проблемы с пропуском с помощью getline()
Используйте его следующим образом std::getline(cin>>ws,a);
Использование ws пропустит пробел.