Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Срауструп CPP.doc
Скачиваний:
4
Добавлен:
05.11.2018
Размер:
4.95 Mб
Скачать

10.6 Ввод-вывод в с

Поскольку текст программ на С и на С++ часто путают, то путают иногда

и потоковый ввод-вывод С++ и функции ввода-вывода семейства printf для

языка С. Далее, т.к. С-функции можно вызывать из программы на С++, то

многие предпочитают использовать более знакомые функции ввода-вывода С.

По этой причине здесь будет дана основа функций ввода-вывода С.

Обычно операции ввода-вывода на С и на С++ могут идти по очереди на

уровне строк. Перемешивание их на уровне посимвольного ввода-вывода

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

непереносимой. Некоторые реализации потоковой библиотеки С++ при допущении

ввода-вывода на С требуют вызова статической функции-члена

ios::sync_with_stdio().

В общем, потоковые функции вывода имеют перед стандартной

функцией С printf() то преимущество, что потоковые функции обладают

определенной типовой надежностью и единообразно определяют вывод

объектов предопределенного и пользовательского типов.

Основная функция вывода С есть

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

и она выводит произвольную последовательность параметров в формате,

задаваемом строкой форматирования format. Строка форматирования состоит

из объектов двух типов: простые символы, которые просто копируются в

выходной поток, и спецификации преобразований, каждая из которых

преобразует и печатает очередной параметр. Каждая спецификация

преобразования начинается с символа %, например

printf("there were %d members present.",no_of_members);

Здесь %d указывает, что no_of_members следует считать целым и печатать

как соответствующую последовательность десятичных цифр. Если

no_of_members==127, то будет напечатано

there were 127 members present.

Набор спецификаций преобразований достаточно большой и обеспечивает

большую гибкость печати. За символом % может следовать:

- необязательный знак минус, задающий выравнивание влево в указанном

поле для преобразованного значения;

d необязательная строка цифр, задающая ширину поля; если в

преобразованном значении меньше символов, чем ширина строки, то оно

дополнится до ширины поля пробелами слева (или справа, если дана

спецификация выравнивания влево); если строка ширины поля начинается

с нуля, то дополнение будет проводится нулями, а не пробелами;

. необязательный символ точка служит для отделения ширины поля от

последующей строки цифр;

d необязательная строка цифр, задающая точность, которая определяет

число цифр после десятичной точки для значений в спецификациях

e или f, или же задает максимальное число печатаемых символов

строки;

* для задания ширины поля или точности может использоваться * вместо

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

содержит значение ширины поля или точности;

h необязательный символ h указывает, что последующая спецификация d,

o, x или u относится к параметру типа короткое целое;

l необязательный символ l указывает, что последующая спецификация d,

o, x или u относится к параметру типа длинное целое;

% обозначает, что нужно напечатать сам символ %; параметр не нужен;

c символ, указывающий тип требуемого преобразования. Символы

преобразования и их смысл следующие:

d Целый параметр выдается в десятичной записи;

o Целый параметр выдается в восьмеричной записи;

x Целый параметр выдается в шестнадцатеричной записи;

f Вещественный или с двойной точностью параметр выдается в

десятичной записи вида [-]ddd.ddd, где число цифр после

точки равно спецификации точности для параметра. Если точность

не задана, печатается шесть цифр; если явно задана точность 0,

точка и цифры после нее не печатаются;

e Вещественный или с двойной точностью параметр выдается в

десятичной записи вида [-]d.ddde+dd; здесь одна цифра перед

точкой, а число цифр после точки равно спецификации точности

для параметра; если она не задана печатается шесть цифр;

g Вещественный или с двойной точностью параметр печатается по той

спецификации d, f или e, которая дает большую точность при

меньшей ширине поля;

c Символьный параметр печатается. Нулевые символы игнорируются;

s Параметр считается строкой (символьный указатель), и печатаются

символы из строки до нулевого символа или до достижения числа

символов, равного спецификации точности; но, если точность

равна 0 или не указана, печатаются все символы до нулевого;

p Параметр считается указателем и его вид на печати зависит от

реализации;

u Беззнаковый целый параметр печатается в десятичной записи.

Несуществующее поле или поле с шириной, меньшей реальной, приведет

к усечению поля. Дополнение пробелами происходит, если только

спецификация ширины поля больше реальной ширины.

Ниже приведен более сложный пример:

char* src_file_name;

int line;

char* line_format = "\n#line %d \"%s\"\n";

main()

{

line = 13;

src_file_name = "C++/main.c";

printf("int a;\n");

printf(line_format,line,src_file_name);

printf("int b;\n");

}

в котором печатается

int a;

#line 13 "C++/main.c"

int b;

Использование printf() ненадежно в том смысле, что нет никакого

контроля типов. Так, ниже приведен известный способ получения

неожиданного результата - печати мусорного значения или чего похуже:

char x;

// ...

printf("bad input char: %s",x);

Однако, эти функции обеспечивают большую гибкость и знакомы

программирующим на С.

Как обычно, getchar() позволяет знакомым способом читать символы из

входного потока:

int i;:

while ((i=getchar())!=EOF) { // символьный ввод C

// используем i

}

Обратите внимание: чтобы было законным сравнение с величиной EOF типа

int при проверке на конец файла, результат getchar() надо помещать в

переменную типа int, а не char.

За подробностями о вводе-выводе на С отсылаем к вашему руководству

по С или книге Кернигана и Ритчи "Язык программирования С".