Guest User

students.cpp

a guest
Dec 7th, 2023
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.10 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <cstring>  //  memset
  3. #include <algorithm>
  4.  
  5. //  Размер буфера с результатами успеваемости
  6. #define SESBUF_SIZE 5
  7. //  Размер массива студентов
  8. #define STUDENT_SIZE    10
  9.  
  10. //  Структура, описывающая студента. По хорошему, надо было делать класс
  11. //  а не структуру.
  12. //  Реальные группы часто имеют буквенно-цифровой номер, поэтому будем
  13. //  хранить данные в виде строки
  14. struct  STUDENT
  15. {
  16.     std::string name;   //  ФИО
  17.     std::string group;  //  Номер группы
  18.     unsigned long   ses[ SESBUF_SIZE ]; //  Успеваемость
  19. };
  20.  
  21. //  Функция вычисляет средний балл
  22. double  calc_average( struct STUDENT& student )
  23. {
  24.     unsigned long   sum = 0;
  25.     for( size_t idx = 0; idx < SESBUF_SIZE; idx++ )
  26.     {
  27.         sum += student.ses[idx];
  28.     }
  29.     return  ((double)sum/(double)SESBUF_SIZE);
  30. }
  31. //  Функция сравнивает структуры по среднему баллу
  32. bool    compare_student( struct STUDENT& s1, struct STUDENT& s2 )
  33. {
  34.     bool    r = false;
  35.     if( calc_average(s1) < calc_average(s2) )
  36.     {
  37.         r = true;
  38.     }
  39.     return  r;
  40. }
  41. //  Функция для вывода в STDOUT данных студента
  42. void    show_student( struct STUDENT& student )
  43. {
  44.     std::cout << "ФИО: '" << student.name << "'\tГруппа: " << student.group
  45.         << " Оценки:";
  46.     for( auto& score:student.ses )
  47.     {
  48.         std::cout << " " << score;
  49.     }
  50.     std::cout << " Средний балл: " << calc_average(student);
  51.     std::cout << std::endl;
  52. }
  53. void    show_good_student( struct STUDENT& student, size_t& good_count )
  54. {
  55.     bool    r = false;
  56.     for( auto& score:student.ses )
  57.     {
  58.         if(score >= 4)
  59.         {
  60.             r = true;
  61.             break;
  62.         }
  63.     }
  64.     if( r )
  65.     {
  66.         good_count++;
  67.         std::cout << "ФИО: '" << student.name
  68.             << "'\tГруппа: " << student.group << std::endl;
  69.     }
  70. }
  71. //  Функция для ввода данных в структуру STUDENT
  72. bool    input_student( struct STUDENT& student )
  73. {
  74.     bool    r = false;
  75.     std::string s;
  76.     std::string err;
  77.     size_t  idx;
  78.     unsigned long   num;
  79.  
  80.     std::cout << "Введите данные студента или . для выхода" << std::endl;
  81.     try
  82.     {
  83.         std::cout << "ФИО: ";
  84.         std::getline( std::cin, student.name );
  85.         if( student.name.compare(".") == 0 )
  86.         {
  87.             err.assign("Ввод данных прерван пользователем");
  88.             throw(err);
  89.         }
  90.         if( student.name.empty() )
  91.         {
  92.             err.assign("ФИО не может быть пустым!");
  93.             throw(err);
  94.         }
  95.         std::cout << "Номер группы: ";
  96.         std::getline( std::cin, student.group );
  97.         if( student.name.compare(".") == 0 )
  98.         {
  99.             err.assign("Ввод данных прерван пользователем");
  100.             throw(err);
  101.         }
  102.         if( student.group.empty() )
  103.         {
  104.             err.assign("Группа не может быть пустой!");
  105.             throw(err);
  106.         }
  107.         std::cout << "Введите успеваемость:" << std::endl;
  108.         for( unsigned int n = 0; n < SESBUF_SIZE; n++ )
  109.         {
  110.             std::cout << "[" << n+1 << "]: ";
  111.             std::getline( std::cin, s );
  112.             if( student.name.compare(".") == 0 )
  113.             {
  114.                 err.assign("Ввод данных прерван пользователем");
  115.                 throw(err);
  116.             }
  117.             num = std::stoul( s, &idx, 0 );
  118.             if( idx < s.length() )
  119.             {
  120.                 if(!(s[idx]==' ' || s[idx]=='\t'))
  121.                 {
  122.                     err.assign("в строке '");
  123.                     err.append(s);
  124.                     err.append("' обнаружен мусор '");
  125.                     err.append(&s[idx]);
  126.                     err.append("'!");
  127.                     throw(err);
  128.                 }
  129.             }
  130.             if( num > 0 && num <= 5 )
  131.             {
  132.                 student.ses[n] = num;
  133.             }
  134.             else
  135.             {
  136.                 err.assign("Допустимый диапазон оценок от 1 до 5");
  137.                 throw(err);
  138.             }
  139.         }
  140.         r = true;
  141.     }
  142.     catch( const std::bad_alloc& ba )
  143.     {
  144.         std::cerr << "Ошибка выделения памяти!" << std::endl;
  145.     }
  146.     catch( const std::invalid_argument& ia )
  147.     {
  148.         std::cerr << "Строка не явялется числом!" << std::endl;
  149.     }
  150.     catch( const std::out_of_range& oor )
  151.     {
  152.         std::cerr << "Значение вне диапазона!" << std::endl;
  153.     }
  154.     catch( const std::string& msg )
  155.     {
  156.         std::cerr << msg << std::endl;
  157.     }
  158.     if( r == false )
  159.     {
  160.         student.name.clear();
  161.         student.group.clear();
  162.         memset( student.ses, 0, sizeof(unsigned long)*SESBUF_SIZE );
  163.     }
  164.     return  r;
  165. }
  166.  
  167. int main( int argc, char* argv[] )
  168. {
  169.     //  Использовать массив - не моя идея, так было в ТЗ
  170.     STUDENT student[STUDENT_SIZE];
  171.     size_t  idx = 0;
  172.     size_t  n_students = 0;
  173.     size_t  good_count = 0;
  174.     bool    retry = false;
  175.  
  176.     while( idx < STUDENT_SIZE )
  177.     {
  178.         if( input_student(student[idx]) )
  179.         {
  180.             show_student( student[idx] );
  181.             idx++;
  182.         }
  183.         else
  184.         {
  185.             std::cout << "0 - прекратить ввод" << std::endl;
  186.             std::cout << "1 - продолжить ввод" << std::endl;
  187.             std::cin >> retry;
  188.             //  Истребляем мусор из STDIN
  189.             while(std::cin.good())
  190.             {
  191.                 if(std::cin.get()=='\n') break;
  192.             }
  193.             if( retry ) continue; else break;
  194.         }
  195.     }
  196.     n_students = idx;
  197.     std::cout << "Введено студентов: " << n_students << std::endl;
  198.     //  Отсортируем студентов в порядке возрастания среднего балла
  199.     //  при помощи функции сравнения compare_student
  200.     std::sort(student, student+idx, compare_student );
  201.  
  202.     std::cout << "Студенты по возрастанию среднего балла" << std::endl;
  203.     for( idx = 0; idx < n_students; idx++ )
  204.     {
  205.         show_student(student[idx]);
  206.     }
  207.     std::cout << "Хорошисты и отличники" << std::endl;
  208.     for( idx = 0; idx < n_students; idx++ )
  209.     {
  210.         show_good_student(student[idx], good_count );
  211.     }
  212.     if( good_count == 0 )
  213.     {
  214.         std::cout << "Не нашлось ни одного студента с 4-кой или 5-кой"
  215.             << std::endl;
  216.     }
  217.     return  0;
  218. }
  219.  
Add Comment
Please, Sign In to add comment