2015-09-01 1 views
1

Я начинаю на C++. Я пытаюсь написать простую программу, которая создает записи student_info. Я создаю массив из structs с именем переменных-членов и вектором оценок домашних заданий. Я хочу читать с терминала ввода cin в этот массив structs. Ниже вы найдете мою попытку сделать это. Я запутался в том, как завершить/выйти из цикла чтения в программе во время запуска программы. Мне нужно продолжить чтение имени и кучу домашних заданий, которые образуют единую запись. Если я удалю is.clear(), тогда он получит только одну запись, когда я набираю имя следующего ученика, программа завершает работу.Завершение ввода при чтении в массив структур из cin

Буду признателен за любые предложения.

#include <cstdlib> 
#include <string> 
#include <iostream> 
#include <vector> 
using namespace std; 

struct student_info{ 
    string name; 
    vector<double> hw_grades; 
}; 

istream& read_single_record (istream& is, student_info& s){ 
    is>>s.name; 
    double x; 
    while(is>>x) 
    { 
    s.hw_grades.push_back(x); 
    } 
    is.clear(); 
    return is;} 

int main() { 
    //read data into an array of student info 
    vector<student_info> vec_st_info; 
    student_info x; 
    while(read_single_record(cin,x)) 
    { 
    vec_st_info.push_back(x); 
    }    
    return 0; 
    } 

Входной образец для программы будет

John 
88 
98 
89 
67 
Sam 
78 
90 
Tom 
89 
90 
76 

Названия следует последовательности домашних заданий классов каждые введенных с помощью ключа «возврата». Количество домашних заданий также не фиксировано.

+1

Для определения того, когда запись завершена, вам нужна фактическая логика. Например, если формат предназначен для всех значений в записи, которая будет введена в одной строке, вы должны использовать 'std :: getline', а затем читать из строки, используя' std :: istringstream'. Если все значения должны быть в отдельных строках и разделены пустой строкой, в этом случае снова будет помогать «std :: getline». Если для оценки, заканчивающей запись, есть контрольное значение (например, '-1'), убедитесь, что вы справляетесь с этим. В противном случае вам может потребоваться прочитать по одному символу за раз, а также вернуть символ, если он не похож на число. – paddy

+0

Спасибо за ваш комментарий. Это упрощенная версия кода в Accelerated C++, я не изменил никаких структурных деталей кода. Я не вижу, что они используют специальную проверку, чтобы определить, когда запись закончена. Есть ли способ, который я могу сказать, назначить символ или ввод, например. cmd + D, чтобы сказать, что запись завершена – Prag1

+0

Это поможет, если вы включили пример в свой вопрос, показывающий, как выглядит вход. – paddy

ответ

0

Это должен быть исправлен путем возврата, когда вы не в состоянии прочитать name:

istream& read_single_record (istream& is, student_info& s) 
{ 
    if(!(is>>s.name)) return is; 
    double x; 
    while(is>>x) 
    { 
    s.hw_grades.push_back(x); 
    } 
    is.clear(); 
    return is; 
} 

Причина этого исправление зависание происходит потому, что поток остается в состоянии ошибки, когда вы не в состоянии прочитать строку. Раньше вы всегда очищали состояние до возвращения.

Смежные вопросы