Advertisement
Guest User

qsort_example.c

a guest
Dec 9th, 2019
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.67 KB | None | 0 0
  1. //  Пример использования функции сортировки qsort
  2. //  Также демонстрируется ввод чисел с обработкой ошибок
  3. #include <stdio.h>
  4. #include <stdlib.h> //  Подключаем функцию быстрой сортировки qsort и преобразования строк в числа strtol
  5. #include <string.h> //  strlen
  6. #include <limits.h> //  LONG_MIN, LONG_MAX
  7.  
  8. //  Размер буфера для преобразования строки в число
  9. #define NUMBUF_SIZE 32
  10.  
  11. //-------------------------------------------------------------------
  12. //  Прототипы функций
  13. //  Функиця считывает строку из файла и преобразует ее в число типа long,
  14. //  которое записывает по указателю l
  15. //  Возвращает 1 в случае удачи или 0 при ошибке ввода, выводит сообщения
  16. //  об ошибках в файл stderr
  17. int get_long( FILE* fp, long* l );
  18. //  Функция выводит содержимое массива в стиле С
  19. void    print_array( char* name, long* array, long array_size );
  20. //-------------------------------------------------------------------
  21. //  Функции сравнения элементов e1 и e2 для qsort
  22. int cmp_long( const void *e1, const void *e2 );
  23. //  Функции сравнения по модулю элементов e1 и e2 для qsort
  24. int cmp_long_abs( const void *e1, const void *e2 );
  25. //  Функции обратного сравнения элементов e1 и e2 для qsort
  26. int cmp_long_rev( const void *e1, const void *e2 );
  27. //-------------------------------------------------------------------
  28.  
  29. //-------------------------------------------------------------------
  30. int main( int argc, char* argv[] )
  31. {
  32.     //  Указатель на первый элемент динамически выделенного массива
  33.     long*   array;
  34.     long    array_size;
  35.     long    index;
  36.     long    sort_mode = 0;
  37.     //  Флаг ошибки
  38.     int eflag;
  39.  
  40.     printf( "Программа демонстрирует сортировку "
  41.             "массива при помощи qsort\n" );
  42.     do
  43.     {
  44.         eflag = 0;
  45.         printf( "Введите количество элементов в массиве: " );
  46.         if( get_long( stdin, &array_size ) )
  47.         {
  48.             if( array_size <= 0 )
  49.             {
  50.                 printf( "Количество элементов в массиве "
  51.                     "должно быть больше нуля!\n" );
  52.  
  53.                 eflag = 1;
  54.             }
  55.         }
  56.         else
  57.         {
  58.             eflag = 1;
  59.         }
  60.     }
  61.     while( eflag );
  62.  
  63.     printf( "Пытаюсь создать массив из %ld элементов... ", array_size );
  64.     fflush( stdout );
  65.     array = (long*)malloc( array_size * sizeof(long) );
  66.     if( array )
  67.     {
  68.         printf( "УСПЕХ\n" );
  69.         printf( "Введите элементы массива:\n" );
  70.         index = 0;
  71.         while( index < array_size )
  72.         {
  73.             printf( "array[%ld] = ", index );
  74.             if( get_long( stdin, &array[index] ) )
  75.             {
  76.                 index++;
  77.             }
  78.         }
  79.         printf( "Содержимое массива до сортировки:\n" );
  80.         print_array( "unsorted_array", array, array_size );
  81.  
  82.         printf( "0 - прямая сортировка\n" );
  83.         printf( "1 - прямая сортировка по модулю\n" );
  84.         printf( "2 - обратная сортировка\n" );
  85.         do
  86.         {
  87.             eflag = 0;
  88.             printf( "Введите режим сортировки (0 - 2): " );
  89.             if( get_long( stdin, &sort_mode ) )
  90.             {
  91.                 if( !((sort_mode >= 0) && (sort_mode <= 2)) )
  92.                 {
  93.                     printf( "Неизвестный режим "
  94.                             "сортировки!\n" );
  95.                     eflag = 1;
  96.                 }
  97.             }
  98.             else
  99.             {
  100.                 eflag = 1;
  101.             }
  102.         }
  103.         while( eflag );
  104.  
  105.         //  Отсортируем массив
  106.         switch( sort_mode )
  107.         {
  108.             case    0:
  109.                 printf( "Сортировка по возрастанию\n" );
  110.                 //  Функции qsort надо передать указатель
  111.                 //  на первый элемент массива, размер
  112.                 //  массива, размер одного элемента
  113.                 //  массива и указатель на функцию для
  114.                 //  сравнения элементов массива
  115.                 qsort( array, array_size,
  116.                         sizeof(long), cmp_long );
  117.                 break;
  118.  
  119.             case    1:
  120.                 printf( "Сортировка по модулю\n" );
  121.                 qsort( array, array_size,
  122.                         sizeof(long), cmp_long_abs );
  123.                 break;
  124.  
  125.             case    2:
  126.                 printf( "Сортировка по убыванию\n" );
  127.                 qsort( array, array_size,
  128.                         sizeof(long), cmp_long_rev );
  129.                 break;
  130.         }
  131.        
  132.         printf( "Содержимое массива после сортировки:\n" );
  133.         print_array( "sorted_array", array, array_size );
  134.  
  135.         //  Не забудем освободить память
  136.         free( array );
  137.     }
  138.     else
  139.     {
  140.         perror( "malloc" );
  141.     }
  142.  
  143.     return  0;
  144. }
  145. //-------------------------------------------------------------------
  146. int get_long( FILE* fp, long* l )
  147. {
  148.     int result = 0;
  149.     char    buf[ NUMBUF_SIZE ];
  150.     long    val;
  151.     char*   end;
  152.     size_t  len;
  153.  
  154.     *l = 0;
  155.     //  Попробуем считать строку из файла
  156.     if( fgets( buf, NUMBUF_SIZE, fp ) )
  157.     {
  158.         len = strlen( buf );
  159.         if( len > 0 )
  160.         {
  161.             if( buf[ len-1 ] == '\n' )
  162.             {
  163.                 len--;
  164.                 buf[ len ] = '\0';
  165.             }
  166.             if( len > 0 )
  167.             {
  168.                 //  Попробуем преобразовать строку
  169.                 //  в число типа long
  170.                 val = strtol( buf, &end, 0 );
  171.                 if( *end == '\0' )
  172.                 {
  173.                     //  Строка была успешно
  174.                     //  преобразована в число
  175.                     //  проверка на переполнение
  176.                     if( val>LONG_MIN && val<LONG_MAX )
  177.                     {
  178.                         *l = val;
  179.                         result++;
  180.                     }
  181.                     else
  182.                     {
  183.                         perror( "strtol" );
  184.                     }
  185.                 }
  186.                 else
  187.                 {
  188.                     fprintf( stderr, "Ошибка! Не удалось "
  189.                         "преобразовать '%s' в число: "
  190.                         "обнаружен мусор '%s'\n",
  191.                         buf, end );
  192.                 }
  193.             }
  194.         }
  195.     }
  196.     else
  197.     {
  198.         perror( "fgets" );
  199.     }
  200.  
  201.     return  result;
  202. }
  203. //-------------------------------------------------------------------
  204. void    print_array( char* name, long* array, long array_size )
  205. {
  206.     long    index;
  207.    
  208.     printf( "%s[%ld] = { ", name, array_size );
  209.     for( index = 0; index < array_size; index++ )
  210.     {
  211.         printf( "%ld", array[index] );
  212.         if( index < array_size - 1 )
  213.         {
  214.             printf( ", " );
  215.         }
  216.         else
  217.         {
  218.             printf( " " );
  219.         }
  220.     }
  221.     printf( "};\n" );
  222. }
  223. //-------------------------------------------------------------------
  224. //  Функции сравнения элементов e1 и e2 для qsort
  225. int cmp_long( const void *e1, const void *e2 )
  226. {
  227.     int result = 0;
  228.  
  229.     if( *(long*)e1 < *(long*)e2 )
  230.     {
  231.         result--;
  232.     }
  233.     else
  234.     if( *(long*)e1 > *(long*)e2 )
  235.     {
  236.         result++;
  237.     }
  238.  
  239.     return  result;
  240. }
  241. //-------------------------------------------------------------------
  242. //  Функции сравнения по модулю элементов e1 и e2 для qsort
  243. int cmp_long_abs( const void *e1, const void *e2 )
  244. {
  245.     int result = 0;
  246.  
  247.     if( abs(*(long*)e1) < abs(*(long*)e2) )
  248.     {
  249.         result--;
  250.     }
  251.     else
  252.     if( abs(*(long*)e1) > abs(*(long*)e2) )
  253.     {
  254.         result++;
  255.     }
  256.  
  257.     return  result;
  258. }
  259. //-------------------------------------------------------------------
  260. //  Функции обратного сравнения элементов e1 и e2 для qsort
  261. int cmp_long_rev( const void *e1, const void *e2 )
  262. {
  263.     int result = 0;
  264.  
  265.     if( *(long*)e1 < *(long*)e2 )
  266.     {
  267.         result++;
  268.     }
  269.     else
  270.     if( *(long*)e1 > *(long*)e2 )
  271.     {
  272.         result--;
  273.     }
  274.  
  275.     return  result;
  276. }
  277. //-------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement