Читаем Linux API. Исчерпывающее руководство полностью

Если аргумент name не содержит значение NULL, в нем должна находиться строка, идентифицирующая аргумент в параметре arg. Эта строка становится частью любого выводимого этими функциями сообщения об ошибке.

Аргумент flags предоставляет возможность управления работой функций getInt() и getLong(). Изначально они ожидают получения строк, содержащих десятичные целые числа со знаком. Путем логического сложения (|) в аргументе flags нескольких констант вида GN_*, определенных в листинге 3.5, можно выбрать иную основу для преобразования и ограничить диапазон чисел неотрицательными значениями или значениями больше нуля.

Листинг 3.5. Заголовочный файл для get_num.c

lib/get_num.h

#ifndef GET_NUM_H

#define GET_NUM_H

#define GN_NONNEG 01 /* Значение должно быть >= 0 */

#define GN_GT_0 02 /* Значение должно быть > 0 */

/* По умолчанию целые числа являются десятичными */

#define GN_ANY_BASE 0100 /* Можно использовать любое основание –

наподобие strtol(3) */

#define GN_BASE_8 0200 /* Значение выражено в виде восьмеричного числа */

#define GN_BASE_16 0400 /* Значение выражено в виде шестнадцатеричного числа */

long getLong(const char *arg, int flags, const char *name);

int getInt(const char *arg, int flags, const char *name);

#endif

lib/get_num.h

Реализации функций getInt() и getLong() показаны в листинге 3.6.

Хотя аргумент flags позволяет принудительно проверять диапазон допустимых значений, рассмотренный в основном тексте, в некоторых случаях в примерах программ такие проверки не запрашиваются, даже если этот запрос кажется вполне логичным. Отказ от проверки диапазона в подобных случаях позволяет не только проводить эксперименты с правильным использованием системных вызовов и вызовов библиотечных функций, но и наблюдать, что произойдет, если будут предоставлены недопустимые аргументы. В приложениях, созданных для реальной работы, обычно вводятся более строгие проверки аргументов командной строки.

Листинг 3.6. Функции для анализа числовых аргументов командной строки

lib/get_num.c

#include

#include

#include

#include

#include

#include "get_num.h"

static void

gnFail(const char *fname, const char *msg, const char *arg, const char *name)

{

fprintf(stderr, "%s error", fname);

if (name!= NULL)

fprintf(stderr, " (in %s)", name);

fprintf(stderr, ": %s\n", msg);

if (arg!= NULL && *arg!= '\0')

fprintf(stderr, " offending text: %s\n", arg);

exit(EXIT_FAILURE);

}

static long

getNum(const char *fname, const char *arg, int flags, const char *name)

{

long res;

char *endptr;

int base;

if (arg == NULL || *arg == '\0')

gnFail(fname, "null or empty string", arg, name);

base = (flags & GN_ANY_BASE)? 0: (flags & GN_BASE_8)? 8:

(flags & GN_BASE_16)? 16: 10;

errno = 0;

res = strtol(arg, &endptr, base);

if (errno!= 0)

gnFail(fname, "strtol() failed", arg, name);

if (*endptr!= '\0')

gnFail(fname, "nonnumeric characters", arg, name);

if ((flags & GN_NONNEG) && res < 0)

gnFail(fname, "negative value not allowed", arg, name);

if ((flags & GN_GT_0) && res <= 0)

gnFail(fname, "value must be > 0", arg, name);

return res;

}

long

getLong(const char *arg, int flags, const char *name)

{

return getNum("getLong", arg, flags, name);

}

int

getInt(const char *arg, int flags, const char *name)

{

long res;

res = getNum("getInt", arg, flags, name);

if (res > INT_MAX || res < INT_MIN)

gnFail("getInt", "integer out of range", arg, name);

return (int) res;

}

lib/get_num.c

3.6. Вопросы переносимости

В этом разделе мы рассмотрим, как создавать портируемые системные программы. В нем будут представлены макросы проверки возможностей и стандартные типы данных системы, определенные спецификацией SUSv3, а затем рассмотрены некоторые другие вопросы портируемости.

3.6.1. Макросы проверки возможностей

Поведение API системных вызовов и вызовов библиотечных функций регулируется различными стандартами (см. раздел 1.3). Одни стандарты определены организациями стандартизации, такими как Open Group (Single UNIX Specification), а другие — двумя исторически важными реализациями UNIX: BSD и System V, выпуск 4 (и объединенным System V Interface Definition).

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

Как один из вариантов, можно задать макрос в исходном коде программы до включения каких-либо заголовочных файлов:

#define _BSD_SOURCE 1

В качестве альтернативы можно воспользоваться ключом — D компилятора языка C:

$ cc — D_BSD_SOURCE prog.c

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

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

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

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