Чтение онлайн

на главную - закладки

Жанры

Программирование для Linux. Профессиональный подход

Самьюэл Алекс

Шрифт:

output_filename = optarg;

break;

case 'v': /* -v или --verbose */

verbose = 1;

break;

case '?': /* Пользователь ввел неверную опцию. */

/* Записываем информацию об использовании программы в поток

stderr и завершаем работу с выдачей кода 1

(аварийное завершение). */

print_usage(stderr, 1);

case -1: /* Опций больше нет. */

break;

default: /*
Какой-то непредвиденный результат. */

abort;

}

 }

 while (next_option != -1);

 /* Обработка опций завершена, переменная OPTIND указывает на

первый аргумент, не являющийся опцией. В демонстрационных

целях отображаем эти аргументы, если задан режим VERBOSE. */

 if (verbose) {

int i;

for (i = optind; i < argc; ++i)

printf("Argument: %s\n", argv[i]);

 }

 /* Далее идет основное тело программы... */

 return 0;

}

Может показаться, что использование функции

getopt_long
приводит к написанию громоздкого кода, но, поверьте, самостоятельный синтаксический анализ опций командной строки — гораздо более трудоемкая задача. Функция
getopt_long
достаточно универсальна и гибка в работе с опциями, но лучше не заниматься сложными вещами. Старайтесь придерживаться традиционной структуры задания опций.

2.1.4. Стандартный ввод-вывод

В стандартной библиотеке языка С определены готовые потоки ввода и вывода (

stdin
и
stdout
соответственно). Они используются функциями
scanf
,
printf
и целым рядом других библиотечных функций. Согласно идеологии UNIX, стандартные потоки можно перенаправлять. Это позволяет образовывать цепочки программ, связанных посредством каналов (конкретный синтаксис перенаправления потоков и работы с каналами можно узнать в документации к интерпретатору команд).

Есть также стандартный поток ошибок:

stderr
. Программы должны направлять предупреждающие сообщения и сообщения об ошибках в него, а не в поток
stdout
. Это позволяет отделять обычные выводные данные от разного рода служебных сообщений. К примеру, стандартный поток вывода можно направить в файл, а сообщения об ошибках, по-прежнему отображать на консоли. Запись в поток
stderr
осуществляется с помощью функции
fprintf
:

fprintf(stderr, ("Error: ..."));

Все три стандартных потока доступны низкоуровневым функциям ввода-вывода (

read
,
write
и т.д.) через дескрипторы файлов. В частности, поток
stdin
имеет дескриптор 0,
stdout
— 1, a
stderr
— 2.

При вызове программы иногда требуется одновременно перенаправить потоки вывода и ошибок в файл или канал. Синтаксис подобной операции зависит от используемого интерпретатора команд. В интерпретаторах семейства Bourne shell (включая

bash
,
который по умолчанию установлен в большинстве дистрибутивов Linux) это делается так:

% program > output_file.txt 2>&1

% program 2>&1 | filter

Запись

2>&1
означает, что файл с дескриптором 2 (
stderr
) объединяется с файле имеющим дескриптор 1 (
stdout
). Обратите внимание на то, что эта запись должна идти после операции перенаправления в файл (первый пример), но перед операцией перенаправления в канал (второй пример).

Поток

stdout
является буферизуемым. Записываемые в него данные не посылаются на консоль (или на другое устройство в случае перенаправления), пока буфер не заполнится, программа не завершит работу нормальным способом или файл
stdout
не будет закрыт. Осуществить принудительное "выталкивание" буфера позволяет функция
fflush
:

fflush(stdout);

В то же время поток

stderr
не буферизуется. Записываемые в него данные сразу попадают на консоль. [6]

Указанная особенность потока

stdout
может приводить к неожиданным результатам. Например, в следующем цикле точка не выводится каждую секунду. Вместо этого все символы сначала помещаются в буфер, а затем целая их группа одновременно выводится на экран, когда буфер оказывается заполненным.

while (1) {

6

В C++ аналогичное различие существует между потоками

cout
и
cerr
. Манипулятор
endl
добавляет в конец потока символ новой строки и вызывает "выталкивание" буфера. Если состояние буфера временно менять не нужно (из соображений производительности, например), воспользуйтесь вместо манипулятора константой
'\n'
.

 printf(".");

 sleep(1);

}

А в этом цикле происходит то, что нам нужно:

while (1) {

 fprintf(stderr, ".");

 sleep(1);

}

2.1.5. Коды завершения программы

Когда программа завершает работу, она уведомляет операционную систему о своем состоянии, посылая ей код завершения, который представляет собой 16-разрядное целое число. По существующему соглашению нулевой код свидетельствует об успешном завершении, а ненулевой указывает на наличие ошибки. Некоторые программы возвращают различные ненулевые коды, обозначая разные ситуации.

В большинстве интерпретаторов команд код завершения последней выполненной программы содержится в специальной переменной

$?
. В показанном ниже примере программа
ls
вызывается дважды, и оба раза запрашивается код ее завершения. В первом случае программа завершается корректно и возвращает нулевой код, во втором случае она сталкивается с ошибкой (указанный в командной строке файл не найден), поэтому код завершения оказывается ненулевым:

% ls /

bin coda etc lib misc nfs proc sbin usr

Поделиться:
Популярные книги

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Магия чистых душ

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.40
рейтинг книги
Магия чистых душ

Барон Дубов

Карелин Сергей Витальевич
1. Его Дубейшество
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Барон Дубов

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Барон диктует правила

Ренгач Евгений
4. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон диктует правила

Попытка возврата. Тетралогия

Конюшевский Владислав Николаевич
Попытка возврата
Фантастика:
альтернативная история
9.26
рейтинг книги
Попытка возврата. Тетралогия

Долгий путь домой

Русич Антон
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
6.20
рейтинг книги
Долгий путь домой

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Завод-3: назад в СССР

Гуров Валерий Александрович
3. Завод
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Завод-3: назад в СССР

Решала

Иванов Дмитрий
10. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Решала

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая

Отдельный танковый

Берг Александр Анатольевич
1. Антиблицкриг
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Отдельный танковый

Метатель. Книга 3

Тарасов Ник
3. Метатель
Фантастика:
попаданцы
альтернативная история
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель. Книга 3

Боярышня Евдокия

Меллер Юлия Викторовна
3. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Евдокия