Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstring> // memset
- #include <algorithm>
- // Размер буфера с результатами успеваемости
- #define SESBUF_SIZE 5
- // Размер массива студентов
- #define STUDENT_SIZE 10
- // Структура, описывающая студента. По хорошему, надо было делать класс
- // а не структуру.
- // Реальные группы часто имеют буквенно-цифровой номер, поэтому будем
- // хранить данные в виде строки
- struct STUDENT
- {
- std::string name; // ФИО
- std::string group; // Номер группы
- unsigned long ses[ SESBUF_SIZE ]; // Успеваемость
- };
- // Функция вычисляет средний балл
- double calc_average( struct STUDENT& student )
- {
- unsigned long sum = 0;
- for( size_t idx = 0; idx < SESBUF_SIZE; idx++ )
- {
- sum += student.ses[idx];
- }
- return ((double)sum/(double)SESBUF_SIZE);
- }
- // Функция сравнивает структуры по среднему баллу
- bool compare_student( struct STUDENT& s1, struct STUDENT& s2 )
- {
- bool r = false;
- if( calc_average(s1) < calc_average(s2) )
- {
- r = true;
- }
- return r;
- }
- // Функция для вывода в STDOUT данных студента
- void show_student( struct STUDENT& student )
- {
- std::cout << "ФИО: '" << student.name << "'\tГруппа: " << student.group
- << " Оценки:";
- for( auto& score:student.ses )
- {
- std::cout << " " << score;
- }
- std::cout << " Средний балл: " << calc_average(student);
- std::cout << std::endl;
- }
- void show_good_student( struct STUDENT& student, size_t& good_count )
- {
- bool r = false;
- for( auto& score:student.ses )
- {
- if(score >= 4)
- {
- r = true;
- break;
- }
- }
- if( r )
- {
- good_count++;
- std::cout << "ФИО: '" << student.name
- << "'\tГруппа: " << student.group << std::endl;
- }
- }
- // Функция для ввода данных в структуру STUDENT
- bool input_student( struct STUDENT& student )
- {
- bool r = false;
- std::string s;
- std::string err;
- size_t idx;
- unsigned long num;
- std::cout << "Введите данные студента или . для выхода" << std::endl;
- try
- {
- std::cout << "ФИО: ";
- std::getline( std::cin, student.name );
- if( student.name.compare(".") == 0 )
- {
- err.assign("Ввод данных прерван пользователем");
- throw(err);
- }
- if( student.name.empty() )
- {
- err.assign("ФИО не может быть пустым!");
- throw(err);
- }
- std::cout << "Номер группы: ";
- std::getline( std::cin, student.group );
- if( student.name.compare(".") == 0 )
- {
- err.assign("Ввод данных прерван пользователем");
- throw(err);
- }
- if( student.group.empty() )
- {
- err.assign("Группа не может быть пустой!");
- throw(err);
- }
- std::cout << "Введите успеваемость:" << std::endl;
- for( unsigned int n = 0; n < SESBUF_SIZE; n++ )
- {
- std::cout << "[" << n+1 << "]: ";
- std::getline( std::cin, s );
- if( student.name.compare(".") == 0 )
- {
- err.assign("Ввод данных прерван пользователем");
- throw(err);
- }
- num = std::stoul( s, &idx, 0 );
- if( idx < s.length() )
- {
- if(!(s[idx]==' ' || s[idx]=='\t'))
- {
- err.assign("в строке '");
- err.append(s);
- err.append("' обнаружен мусор '");
- err.append(&s[idx]);
- err.append("'!");
- throw(err);
- }
- }
- if( num > 0 && num <= 5 )
- {
- student.ses[n] = num;
- }
- else
- {
- err.assign("Допустимый диапазон оценок от 1 до 5");
- throw(err);
- }
- }
- r = true;
- }
- catch( const std::bad_alloc& ba )
- {
- std::cerr << "Ошибка выделения памяти!" << std::endl;
- }
- catch( const std::invalid_argument& ia )
- {
- std::cerr << "Строка не явялется числом!" << std::endl;
- }
- catch( const std::out_of_range& oor )
- {
- std::cerr << "Значение вне диапазона!" << std::endl;
- }
- catch( const std::string& msg )
- {
- std::cerr << msg << std::endl;
- }
- if( r == false )
- {
- student.name.clear();
- student.group.clear();
- memset( student.ses, 0, sizeof(unsigned long)*SESBUF_SIZE );
- }
- return r;
- }
- int main( int argc, char* argv[] )
- {
- // Использовать массив - не моя идея, так было в ТЗ
- STUDENT student[STUDENT_SIZE];
- size_t idx = 0;
- size_t n_students = 0;
- size_t good_count = 0;
- bool retry = false;
- while( idx < STUDENT_SIZE )
- {
- if( input_student(student[idx]) )
- {
- show_student( student[idx] );
- idx++;
- }
- else
- {
- std::cout << "0 - прекратить ввод" << std::endl;
- std::cout << "1 - продолжить ввод" << std::endl;
- std::cin >> retry;
- // Истребляем мусор из STDIN
- while(std::cin.good())
- {
- if(std::cin.get()=='\n') break;
- }
- if( retry ) continue; else break;
- }
- }
- n_students = idx;
- std::cout << "Введено студентов: " << n_students << std::endl;
- // Отсортируем студентов в порядке возрастания среднего балла
- // при помощи функции сравнения compare_student
- std::sort(student, student+idx, compare_student );
- std::cout << "Студенты по возрастанию среднего балла" << std::endl;
- for( idx = 0; idx < n_students; idx++ )
- {
- show_student(student[idx]);
- }
- std::cout << "Хорошисты и отличники" << std::endl;
- for( idx = 0; idx < n_students; idx++ )
- {
- show_good_student(student[idx], good_count );
- }
- if( good_count == 0 )
- {
- std::cout << "Не нашлось ни одного студента с 4-кой или 5-кой"
- << std::endl;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment