Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

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

char c = 'a'; /* символ завершения ввода для функции f */

char* p = 0;  /* последний символ, считанный функцией f */

char a[177];  /* буфер ввода */

char* f;    /* считывает данные в буфер a;

                 возвращает указатель на первый считанный символ */

Кроме того, выбирайте осмысленные имена.

<p id="AutBody_Root556"><strong>27.6. Ввод-вывод: заголовок stdio</strong></p>

 В языке С нет потоков ввода-вывода iostream, поэтому мы используем стандартный механизм ввода-вывода языка С, определенный в заголовочном файле . Эквивалентами потоков ввода и вывода cin и cout из языка С++ в языке С являются потоки stdin и stdout. Стандартные средства ввода-вывода языка С и потоки iostream могут одновременно использоваться в одной и той же программе (для одних и тех же потоков ввода-вывода), но мы не рекомендуем это делать. Если вам необходимо совместно использовать эти механизмы, хорошенько разберитесь в них (обратите особое внимание на функцию ios_base::sync_with_stdio), используя хороший учебник. См. также раздел Б.10.

<p id="AutBody_Root557"><strong>27.6.1. Вывод</strong></p>

Наиболее популярной и полезной функцией библиотеки stdio является функция printf. Основным предназначением функции printf является вывод С-строки.

#include

void f(const char* p)

{

  printf("Hello, World!\n");

  printf(p);

}

Это не очень интересно. Намного интереснее то, что функция printf может получать любое количество аргументов и начальную управляющую строку, которая определяет, как вывести дополнительные аргументы. Объявление функции printf в языке C выглядит следующим образом:

int printf(const char* format, ...);

Многоточие (...) означает “и, возможно, остальные аргументы”. Мы можем вызвать функцию printf так:

void f1(double d, char* s, int i, char ch)

{

  printf("double %g string %s int %d char %c\n", d, s, i, ch);

}

где символы %g означают: “Напечатать число с плавающей точкой, используя универсальный формат”, символы %s означают: “Напечатать С-строку”, символы %d означают: “Напечатать целое число, используя десятичные цифры,” а символы %c означают: “Напечатать символ”. Каждый такой спецификатор формата связан со следующим, до поры до времени не используемым аргументом, так что спецификатор %g выводит на экран значение переменной d; %s — значение переменной s, %d — значение переменной i, а %c — значение переменной ch. Полный список форматов функции printf приведен в разделе Б.10.2.

  К сожалению, функция printf не является безопасной с точки зрения типов. Рассмотрим пример.

char a[] = { 'a', 'b' };      /* нет завершающего нуля */

void f2(char* s, int i)

{

  printf("goof %s\n", i);     /* неперехваченная ошибка */

  printf("goof %d: %s\n", i); /* неперехваченная ошибка */

  printf("goof %s\n", a);     /* неперехваченная ошибка */}

Интересен эффект последнего вызова функции printf: она выводит на экран каждый байт участка памяти, следующего за элементом a[1], пока не встретится нуль. Такой вывод может состоять из довольно большого количества символов.

Недостаток проверки типов является одной из причин, по которым мы предпочитаем потоки iostream, несмотря на то, что стандартный механизм ввода-вывода, описанный в библиотеке stdio языков C и C++, работает одинаково. Другой причиной является то, что функции из библиотеки stdio не допускают расширения: мы не можем расширить функцию printf так, чтобы она выводила на экран значения переменных вашего собственного типа. Для этого можно использовать потоки iostream. Например, нет никакого способа, который позволил бы вам определить свой собственный спецификатор формата %Y для вывода структуры struct Y.

Существует полезная версия функции printf, принимающая в качестве первого аргумента дескриптор файла.

int fprintf(FILE* stream, const char* format, ...);

Рассмотрим пример.

fprintf(stdout,"Hello, World!\n"); // идентично

                                   // printf("Hello,World!\n");

FILE* ff = fopen("My_file","w");   // открывает файл My_file

                                   // для записи

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

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

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Билл де Ора , Майкл Хайгард , Нил Форд

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