Вход/Регистрация
Язык программирования Си. Издание 3-е, исправленное
вернуться

Ритчи Деннис М.

Шрифт:

printf(s); /* НЕВЕРНО, если в s есть % */

printf("%s", s); /* ВЕРНО всегда */

Функция sprintf выполняет те же преобразования, что и printf, но вывод запоминает в строке

int sprintf(char *string, char *format, arg1, arg2,…)

Эта функция форматирует arg1, arg2 и т. д. в соответствии с информацией, заданной аргументом format, как мы описывали ранее, но результат помещает не в стандартный вывод, а в string. Заметим, что строка string должна быть достаточно большой, чтобы в ней поместился результат.

Упражнение 7.2. Напишите программу, которая будет печатать разумным способом любой ввод. Как минимум она должна уметь печатать неграфические символы в восьмеричном или шестнадцатеричном виде (в форме, принятой на вашей машине), обрывая длинные текстовые строки.

7.3 Списки аргументов переменной длины

Этот параграф содержит реализацию минимальной версии printf. Приводится она для того, чтобы показать, как надо писать функции со списками аргументов переменной длины, причем такие, которые были бы переносимы. Поскольку нас главным образом интересует обработка аргументов, функцию minprintf напишем таким образом, что она в основном будет работать с задающей формат строкой и аргументами; что же касается форматных преобразований, то они будут осуществляться с помощью стандартного printf.

Объявление стандартной функции printf выглядит так:

int printf(char *fmt, …)

Многоточие в объявлении означает, что число и типы аргументов могут изменяться. Знак многоточие может стоять только в конце списка аргументов. Наша функция minprintf объявляется как

void minprintf(char *fmt, …)

поскольку она не будет выдавать число символов, как это делает printf.

Вся сложность в том, каким образом minprintf будет продвигаться вдоль списка аргументов, - ведь у этого списка нет даже имени. Стандартный заголовочный файл ‹stdarg.h› содержит набор макроопределений, которые устанавливают, как шагать по списку аргументов. Наполнение этого заголовочного файла может изменяться от машины к машине, но представленный им интерфейс везде одинаков.

Тип va_list служит для описания переменной, которая будет по очереди указывать на каждый из аргументов; в minprintf эта переменная имеет имя ap (от "argument pointer" - указатель на аргумент). Макрос va_start инициализирует переменную ap) чтобы она указывала на первый безымянный аргумент. К va_start нужно обратиться до первого использования ap. Среди аргументов по крайней мере один должен быть именованным: от последнего именованного аргумента этот макрос "отталкивается" при начальной установке.

Макрос va_arg на каждом своем вызове выдает очередной аргумент, а ap передвигает на следующий: но имени типа он определяет тип возвращаемого значения и размер шага для выхода на следующий аргумент. Наконец, макрос va_end делает очистку всего, что необходимо. К va_end следует обратиться перед самым выходом из функции.

Перечисленные средства образуют основу нашей упрощенной версии prinf.

#include ‹stdarg.h›

/* minprintf: минимальный printf с переменным числом аргументов */

void minprintf(char *fmt, …)

{

 va_list ap; /* указывает на очередной безымянный аргумент */

 char *p, *sval;

 int ival;

 double dval;

 va_start(ap, fmt); /* устанавливает ap на 1-й безымянный аргумент */

 for (p=fmt; *p; p++) {

if (*p !='%') {

putchar(*p);

continue;

}

switch (*++p) {

case 'd':

ival = va_arg(ap, int);

printf ("%d", ival);

break;

case 'f':

dval = va_arg(ap, double);

printf("%f", dval);

break;

case 's':

for (sval = va_arg(ap, char *); *sval; sval++)

putchar(*sval);

break;

default:

putchar(*p);

break;

}

 }

 va_end(ap); /* очистка, когда все сделано */

}

Упражнение 7.3. Дополните minprintf другими возможностями printf.

  • Читать дальше
  • 1
  • ...
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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