Linux программирование в примерах
Шрифт:
Bush George 41 601322400
Reagan Ronald 40 348861600
Carter James 39 222631200
В
ch06-sortemp.c
приведена простая программа, которая считывает этот файл в массив struct employee
, а затем сортирует его, используя две только что представленные функции сравнения. 1 /* ch06-sortemp.c --- Демонстрирует qsort с двумя функциями сравнения. */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 struct employee {
8 char lastname[30];
9 char firstname[30];
10 long emp_id;
11 time_t start_date;
12 };
13
14 /* emp_name_id_compare ---
сравнение по имени, затем no ID */
15
16 int emp_name_id_compare(const void *e1p, const void *e2p)
17 {
/* ...как показано ранее, опущено для экономии места... */
39 }
40
41 /* emp_seniority_compare --- сравнение по старшинству */
42
43 int emp_seniority_compare(const void *e1p, const void *e2p)
44 {
/* ...как показано ранее, опущено для экономии места... */
58 }
59
60 /* main --- демонстрация сортировки */
61
62 int main(void)
63 {
64 #define NPRES 10
65 struct employee presidents[NPRES];
66 int i, npres;
67 char buf[BUFSIZ];
68
69 /* Очень простой код для чтения данных: */
70 for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, stdin) != NULL;
71 npres++) {
72 sscanf(buf, "%s %s %ld %ld\n",
73 presidents[npres].lastname,
74 presidents[npres].firstname,
75 &presidents[npres].emp_id,
76 &presidents[npres].start_date);
77 }
78
79 /* npres теперь содержит число прочитанных строк. */
80
81 /* Сначала сортировка по имени */
82 qsort(presidents, npres, sizeof(struct employee), emp_name_id_compare);
83
84 /* Вывести результат */
85 printf("Sorted by name:\n");
86 for (i = 0; i < npres; i++)
87 printf("\t%s %s\t%d\t%s",
88 presidents[i].lastname,
89 presidents[i].firstname,
90 presidents[i].emp_id,
91 ctime(&presidents[i].start_date));
92
93 /*
Теперь сортировка по старшинству */
94 qsort(presidents, npres, sizeof(struct employee), emp_seniority_compare);
95
96 /* И снова вывести */
97 printf("Sorted by seniority:\n");
98 for (i = 0; i < npres; i++)
99 printf("\t%s %s\t%d\t%s",
100 presidents[i].lastname,
101 presidents!i].firstname,
102 presidents[i].emp_id,
103 ctime(&presidents[i].start_date));
104 }
Строки 70–77 считывают данные. Обратите внимание, что любое использование
scanf
требует от входных данных «хорошего поведения». Если, например, какое-нибудь имя содержит более 29 символов, возникает проблема. В данном случае, мы вне опасности, но в коде изделия нужно быть гораздо более осмотрительным. Строка 82 сортирует данные по имени и по ID сотрудника, а затем строки 84–91 выводят отсортированные данные. Сходным образом строка 94 пересортировывает данные, на этот раз по старшинству, а строки 97–103 выводят результаты. После компилирования и запуска программа выдает следующие результаты:
$ ch06-sortemp < presdata.txt
Sorted by name:
Bush George 41 Fri Jan 20 13:00:00 1989
Bush George 43 Sat Jan 20 13:00:00 2001
Carter James 39 Thu Jan 20 13:00:00 1977
Clinton William 42 Wed Jan 20 13:00:00 1993
Reagan Ronald 40 Tue Jan 20 13:00:00 1981 \
Sorted by seniority:
Carter James 39 Thu Jan 20 13:00:00 1977
Reagan Ronald 40 Tue Jan 20 13:00:00 1981
Bush George 41 Fri Jan 20 13:00:00 1989
Clinton William 42 Wed Jan 20 13:00:00 1993
Bush George 43 Sat Jan 20 13:00:00 2001
(Мы использовали 1 час пополудни как приблизительное время, когда все президенты начали работать.) [66]
Стоит заметить одну вещь:
qsort
переставляет данные в массиве. Если каждый элемент массива представляет собой большую структуру, при сортировке массива большое количество данных будут копироваться туда-сюда. Вместо этого может оказаться выгодным создать отдельный массив указателей, каждый из которых указывает на один элемент массива. Затем использовать qsort
для сортировки массива указателей, получая доступ к несортированным данным через сортированные указатели.66
Вывод, показанный здесь, относится к US Eastern Standard Time. Вы получите различные результаты для одних и тех же программ и данных, если используете другой часовой пояс — Примеч. автора.
Поделиться:
Популярные книги
Личный аптекарь императора
1. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Диверсант
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Воронцов. Перезагрузка
1. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Локки 9. Потомок бога
9. Локки
Фантастика:
фэнтези
попаданцы
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Рассвет русского царства
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Сирийский рубеж 3
7. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
На границе империй. Том 7. Часть 4
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Локки 11. Потомок бога
11. Локки
Фантастика:
героическая фантастика
боевая фантастика
фэнтези
юмористическое фэнтези
5.00
рейтинг книги
Наследник Теней
3. Хозяин Теней
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследие Маозари 4
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Личник
3. Ермак
Фантастика:
альтернативная история
6.33
рейтинг книги
Последний Паладин. Том 3
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Вечный. Книга VI
6. Вечный
Фантастика:
рпг
фэнтези
5.00
рейтинг книги
Вперед в прошлое 9
9. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00