Linux программирование в примерах
Шрифт:
14 /* emp_id_compare --- сравнение по ID */
15
16 int emp_id_compare(const void *e1p, const void *e2p)
17 {
18 const struct employee *e1, *e2;
19
20 e1 = (const struct employee*)e1p;
21 e2 = (const struct employee*)e2p;
22
23 if (e1->emp_id < e2->emp_id)
24 return -1;
25 else if (e1->emp_id == e2->emp_id)
26 return 0;
27 else
28 return 1;
29 }
30
31 /* print_employee --- напечатать структуру сотрудника */
32
33 void print_employee(const struct employee *emp)
34 {
35 printf("%s %s\t%d\t%s", emp->lastname, emp->firstname,
36 emp->emp_id, ctime(&emp->start_date));
37 }
Строки 7–12 определяют
struct employee
; она та же, что и раньше. Строки 16–29 служат в качестве функции сравнения как для qsort
, так и для bsearch
. Они сравнивают лишь ID сотрудников. Строки 33–37 определяют print_employee
, которая является удобной функцией для печати структуры, поскольку это делается из разных мест. 39 /* main --- демонстрация сортировки */
40
41 int main(int argc, char **argv)
42 {
43 #define NPRES 10
44 struct employee presidents[NPRES];
45 int i, npres;
46 char buf[BUFSIZ];
47 struct employee *the_pres;
48 struct employee key;
49 int id;
50 FILE *fp;
51
52 if (argc != 2) {
53 fprintf(stderr, "usage: %s datafile\n", argv[0]);
54 exit(1);
55 }
56
57 if ((fp = fopen(argv[1], "r")) == NULL) {
58 fprintf(stderr, "%s: %s: could not open: %s\n", argv[0],
59 argv[1], strerror(errno));
60 exit(1);
61 }
62
63 /* Очень простой код для чтения данных: */
64 for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, fp) != NULL;
65 npres++) {
66 sscanf(buf, "%s %s %ld %ld",
67 presidents[npres].lastname,
68 presidents[npres].firstname,
69 &presidents[npres].emp_id,
70 &presidents[npres].start_date);
71 }
72 fclose(fp);
73
74 /* В npres теперь число действительно прочитанных строк. */
75
76 /* Сначала отсортировать по id */
77 qsort(presidents, npres, sizeof(struct employee), emp_id_compare);
78
79 /* Напечатать результат */
80 printf("Sorted by ID:\n");
81 for (i = 0; i < npres; i++) {
82 putchar('\t');
83 print_employee(&presidents[i]);
84 }
85
86 for (;;) {
87 printf("Enter ID number: ");
88 if (fgets(buf, BUFSIZ, stdin) == NULL)
89 break;
90
91 sscanf(buf, "%d\n", &id);
92 key.emp_id = id;
93 the_pres = (struct employee*)bsearch(&key, presidents,
94 npres, sizeof(struct employee), emp_id_compare);
95
96 if (the_pres != NULL) {
97 printf("Found: ");
98 print_employee(the_pres);
99 } else
100 printf("Employee with ID %d not found'\n", id);
101 }
102
103 putchar('\n'); /* Напечатать в конце символ новой строки. */
104
105 exit(0);
106 }
Функция
main
начинается с проверки аргументов (строки 52–55). Затем она читает данные из указанного файла (строки 57–72). Стандартный ввод для данных сотрудников использоваться не может, поскольку он зарезервирован для запроса у пользователя ID искомого сотрудника. Строки 77–84 сортируют, а затем печатают данные. Затем программа входит в цикл, начинающийся со строки 86. Она запрашивает идентификационный номер сотрудника, выходя из цикла по достижению конца файла. Для поиска в массиве мы используем
struct employee
с именем key
. Достаточно лишь установить в его поле emp_id введенный номер ID; другие поля при сравнении не используются (строка 92). Если найден элемент с подходящим ключом,
bsearch
возвращает указатель на него. В противном случае она возвращает NULL
. Возвращенное значение проверяется в строке 96, и осуществляется нужное действие. Наконец, строка 102 выводит символ конца строки, чтобы системное приглашение появилось с новой строки. Вот что появляется после компилирования и запуска программы:
Поделиться:
Популярные книги
Матабар V
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Ермак. Телохранитель
2. Ермак
Фантастика:
альтернативная история
7.00
рейтинг книги
Кукловод
4. Династия
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Цеховик. Книга 1. Отрицание
1. Цеховик
Фантастика:
попаданцы
альтернативная история
5.75
рейтинг книги
Девочка из прошлого
3. Айдаровы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Бастард Императора. Том 6
6. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Оружейникъ
2. Александр Агренев
Фантастика:
альтернативная история
9.17
рейтинг книги
Последний Паладин. Том 6
6. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Первый среди равных. Книга IX
9. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Чиновникъ Особых поручений
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
КАМЕРГЕРСКИЙ ПЕРЕУЛОК
Фантастика:
фэнтези
6.00
рейтинг книги
Эволюционер из трущоб. Том 2
2. Эволюционер из трущоб
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Болезни ног и варикозное расширение вен. Лечение и профилактика
Дом и Семья:
здоровье и красота
6.25
рейтинг книги
Истребители. Трилогия
Фантастика:
альтернативная история
7.30