Читаем Linux программирование в примерах полностью

24    if (strcmp(gr->gr_mem[i], argv[i]) == 0) /* Если пользователь найден... */

25     print_group(gr); /* Вывести запись */

26

27  endgrent();

28

29  exit(0);

30 }

Функция main() сначала проверяет ошибки (строки 17–20). Основным компонентом программы является вложенный цикл. Внешний цикл (строка 22) перечисляет все записи базы данных группы. Внутренний цикл (строка 23) перечисляет всех членов массива gr_mem. Если один из членов соответствует имени из командной строки (строка 24), для печати записи вызывается print_group() (строка 25):

32 /* print_group --- печать записи группы */

33

34 void

35 print_group(const struct group *gr)

36 {

37  int i;

38

39  printf("%s:%s:%ld:gr->gr_name, gr->gr_passwd, (long)gr->gr_gid);

40

41  for (i = 0; gr->gr_mem[i] != NULL; i++) {

42   printf("%s", gr->gr_mem[i]);

43   if (gr->gr_mem[i+1) != NULL)

44    putchar(',');

45  }

46

47  putchar('\n');

48 }

Функция print_group() (строки 34–48) проста, ее логика подобна логике main() для печати списка членов. Члены списка группы разделены запятыми; поэтому тело цикла до вывода запятой должно проверить, что следующий элемент в массиве не является NULL. Этот код работает правильно, даже если в группе нет членов. Однако мы знаем, что для этой программы есть члены, иначе print_group() не была бы вызвана! Вот что происходит при запуске программы:

$ ch06-groupinfo arnold

mail:x:12:mail,postfix,arnold

uucp:x:14:uucp,arnold

floppy:x:19:arnold

devel:x:42:miriam,arnold

arnold:x:2076:arnold

<p>6.4. Терминалы: <code>isatty()</code></p>

Модель стандартного ввода, стандартного вывода и стандартной ошибки Linux/Unix препятствует специальной трактовке устройств ввода и вывода. Программам обычно не нужно знать или беспокоиться о том, направляется ли их вывод на терминал, в файл, канал, физическое устройство или что-то еще.

Однако иногда бывают моменты, когда программе действительно нужно знать, с какого рода файлом связан файловый дескриптор. Семейство вызовов stat() часто предоставляет достаточно сведений обычный файл, каталог, устройство и т.д. Хотя иногда даже этого недостаточно, и для интерактивных программ, в частности, вам может потребоваться знать, не представляет ли дескриптор файла tty.

tty (сокращение для Teletype, одного из ранних производителей компьютерных терминалов) является любым устройством, представляющим терминал, т.е. нечто, что человек мог бы использовать для взаимодействия с компьютером. Это может быть либо аппаратное устройство, такое, как клавиатура и монитор персонального компьютера, или старинный терминал видеодисплея, соединенный с компьютером через последовательный порт или модем, или программный псевдотерминал, такой, который используется в оконных системах и при сетевых регистрациях.

Различить можно с помощью isatty().

#include /* POSIX */

int isacty(int desc);

Эта функция возвращает 1, если дескриптор файла desc представляет терминал, в противном случае 0. В соответствии с POSIX isatty() может установить errno для указания ошибки; поэтому до вызова isatty() следует установить errno в 0, а затем проверить ее значение, если был возвращен 0. (Справочная страница GNU/Linux isatty(3) не упоминает об использовании errno.) Стандарт POSIX также указывает, что просто возврат isatty() 1 не означает, что на другом конце дескриптора файла находится человек!

Одним местом, где используется isatty(), является современная версия ls, в которой имена файлов по умолчанию печатаются в столбцы, если терминалом является стандартный вывод, а если нет, они печатаются по одной на строчку.

<p>6.5. Рекомендуемая литература</p>

1. Mastering Algorithms With C by Kyle Loudon. O'Reilly & Associates, Sebastopol, California, USA, 1999. ISBN: 1-56592-453-3.

Эта книга предоставляет практическое, утилитарное введение в алгоритмы и структуры данных с использованием С, освещая среди прочих вещей таблицы хэшей, деревья, сортировку и поиск.

2. The Art of Computer Programming Volume 3. Sorting and Searching, 2nd edition, by Donald E. Knuth Addison-Wesley, Reading Massachusetts, USA, 1998. ISBN: 0-201-89685-0.[71]

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных