C++ Программирование в среде С++ Builder 5

Ввод и вывод в С


printf () является функцией стандартной библиотеки с переменным числом аргументов. Она всегда имеет по крайней мере один аргумент — строку формата, чаще всего строковый литерал. Строка может содержать спецификаторы преобразования. Функция сканирует строку и передает ее символы на стандартный вывод программы, по умолчанию консоль, пока не встретит спецификатор преобразования. В этом случае printf () ищет дополнительный аргумент, который форматируется и выводится в соответствии со спецификацией. Таким образом, вызов printf () должен содержать столько дополнительных аргументов, сколько спецификаторов преобразования имеется в строке формата.

Спецификация преобразования

Синтаксис спецификатора преобразования имеет такой вид:

%[флаги] [поле][.точность][размер]символ типа

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

Таблица 3.4. Элементы спецификатора преобразования



Элемент

Символ

Аргумент

Описание

флаг - Выровнять вывод по левому краю поля.
0 Заполнить свободные позиции нулями вместо пробелов.
+ Всегда выводить знак числа.
пробел Вывести пробел на месте знака, если число положительное.
# Вывести 0 перед восьмеричным или Ох перед шестнадцатеричным значением.
поле число Минимальная ширина поля вывода.
точность число Для строк — максимальное число выводимых символов; для целых — минимальное число выводимых цифр; для вещественных — число цифр дробной части.
размер h Аргумент -- короткое целое.
1 Аргумент — длинное целое.
L Аргумент имеет тип long double.
Элемент

Символ

Аргумент

Описание

символ типа d целое Форматировать как десятичное целое со знаком.
i целое То же, что и d.
о целое Форматировать как восьмеричное без знака.
U целое Форматировать как десятичное без знака.
х целое Форматировать как шестнадцатеричное в нижнем регистре.
Х целое Форматировать как шестнадцатеричное в верхнем регистре.
f вещественное Вещественное в форме [-]dddd.dddd.
е вещественное Вещественное в форме [-]d.dddde[+|-]dd.
Е вещественное То же, что и е, с заменой е на Е.
ё вещественное Использовать форму f или е в зависимости от величины числа и ширины поля.
G вещественное То же, что и g — но форма f или Е.
с, символ Вывести одиночный символ.
s строка Вывести строку.
п указатель Аргумент — указатель на переменную типа int. В нее записывается количество выведенных к данному моменту символов.
р указатель Вывести указатель в виде шестнадцатеричного числа ХХХХХХХХ.
<
Как видите, флаги задают “стиль” представления чисел на выводе, поле и точность определяют характеристики поля, отведенного под вывод аргумента, размер уточняет тип аргумента и символ_типа задает собственно тип преобразования. Следующий пример показывает возможности форматирования функции printf () . Советую не полениться и поэкспериментировать с этим кодом, меняя флаги и параметры поля вывода.

Листинг 3.1. Возможности функции printf ()

/*

** Printf.с: Демонстрация форматирования вывода на консоль

** функцией printf().

* /

#pragma hdrstop

#include <stdio.h>

#include <conio.h>

#pragma argsused

int main(int argc, char *argv[])

{

double p = 27182.81828;

int j = 255;

char s[] = "Press any key...";

/* Вывести 4 цифры; вывести обязательный знак: */

printf("Test integer formatting: %13.4d %4-8d\n", j, j);

/* Вывести по левому краю со знаком; заполнить нулями: */ printf("More integer formatting: %-+13d % 08d\n", j, j);

printf("Test octal and hex: %#13o %#8.6x\n", j, j);

printf("\nTest e and f conversion: %13.7e %8.2f\n", p, p) ;

printf("\n%s", s); /* Вывести строку подсказки. */

getch () ;

return 0;

}



Рис. 3.1 Тестирование функции printf()



Прием, позволяющий компилировать программу с главным файлом .с (а не .срр), описан в предыдущей главе в замечании к разделу о консольных приложениях. Конечно, показанная программа будет компилироваться и в режиме C++.



Escape-последовательности



В строках языка С для представления специальных (например, непечатаемых) символов используются escape-последователъности, состоящие из обратной дробной черты, за которой следует один или несколько символов. (Название появилось по аналогии с командами управления терминалом или принтером, которые действительно представляли собой последовательности переменной длины, начинающиеся с кода ESC.) В приведенных примерах функции printf () вы уже встречались с одной такой последовательностью — \n. Сама обратная косая черта называется escape-символом..



В таблице 3.5 перечислены возможные esc-последовательности.



Таблица 3.5. Escape-последовательности языка С



Последовательность

Название



Описание

Звонок Подает звуковой сигнал.
\b Возврат на шаг Возврат курсора на одну позицию назад.
\f Перевод страницы Начинает новую страницу.
\n Перевод строки Начинает новую строку.
\r Возврат каретки Возврат курсора к началу текущей строки.
\t Табуляция Переход к следующей позиции табуляции.
\v Вертикальная табуляция Переход на несколько строк вниз.
\\ Выводит обратную дробную черту.
\' Выводит апостроф (одинарную кавычку).
\" Выводит кавычку (двойную).
Кроме того, esc-последовательности могут представлять символы в ASCII-коде — в восьмеричном или шестнадцатеричном формате:

\000 От одной до трех восьмеричных цифр после esc-символа.
\хНН или \ХНН Одна или две шестнадцатеричных цифры после esc-символа.
Функции ввода строки — scanf() и gets()

В языке С для ввода имеется “зеркальный двойник” printf() — функция scant (). Функция читает данные со стандартного ввода, по умолчанию — клавиатуры. Она так же, как и printf () , принимает строку формата с несколькими спецификаторами преобразования и несколько дополнительных параметров, которые должны быть адресами переменных, куда будут записаны введенные значения.



В языке С функция не может изменять значение передаваемых ей аргументов, поскольку ей передается только временная копия содержимого соответствующей переменной. Это называется передачей параметра.по значению. В языке Pascal возможна также передача по ссылке, позволяющая функции изменить саму переменную-аргумент. Параметр, передаваемый по ссылке, объявляется с ключевым словом var. В С нет автоматического механизма передачи по ссылке. Чтобы передать из функции некоторое значение через параметр, ее вызывают с указателем на переменную (грубо говоря, ее адресом), подлежащую модификации. Функция не может изменить переданный ей аргумент, т. е. сам адрес, но она может записать информацию в память по этому адресу. Адрес получают с помощью операции &, например, SaVar. Подробнее мы обсудим это, когда будем говорить об указателях.



Примером вызова scanf () может служить следующий фрагмент кода:

int age;

printf("Enter your age: "); //' Запросить ввод возраста

// пользователя. scanf ("%d", &age); // Прочитать введенное число.

Функция возвращает число успешно сканированных полей, которое в приведенном фрагменте игнорируется. При необходимости вы можете найти полную информацию по scanf () в оперативной справке C++Builder. Однако следует сказать, что программисты не любят эту функцию и пользуются ей очень редко. Причина в том, что опечатка при вводе (скажем, наличие буквы в поле, предполагающем ввод числа и т. п.) может привести к непредсказуемым результатам. Контролировать корректность ввода и обеспечить адекватную реакцию программы на ошибку при работе со scanf () довольно сложно. Поэтому часто предпочитают прочитать целиком всю строку, введенную пользователем, в некоторый буфер, а затем самостоятельно декодировать ее, выделяя отдельные лексемы и преобразуя их в соответствующие значения. В этом случае можно контролировать каждый отдельный шаг процесса преобразования.

Ввод строки с клавиатуры производится функцией gets ():

char s[80] ;

gets (s) ;

Буфером, в который помещается введенная строка, является здесь символьный массив s [ ]. О массивах чуть позже, пока же скажем, что в данном случае определяется буфер, достаточный для хранения строки длиной в 79 символов — на единицу меньше, чем объявленная длина массива. Одна дополнительная позиция необходима для хранения признака конца строки; все строки в С должны оканчиваться нуль-символом \0, о котором программисту, как правило, заботиться не нужно. Функции обработки строк сами распознают эти символы или, как gets (), автоматически добавляют нуль-символ в конец строки-результата. Функция gets () возвращает данные через параметр, поэтому, как говорилось выше, ей нужно передать в качестве параметра адрес соответствующего символьного массива. Операция взятия адреса, однако, здесь не нужна, поскольку имя массива (без индекса) само по себе является указателем на начало массива. Забегая вперед, скажем, что показанная нотация эквивалентна

gets(&s[0]);

// Аргумент - указатель на начальный элемент

// массива s.

Для преобразования строк, содержащих цифровое представление чисел, в численные типы данных могут применяться функции atoi(), ato1 () и atof (). Они преобразуют строки соответственно в целые, длинные целые и вещественные числа (типы int, long и double). Входная строка может содержать начальные пробелы; первый встреченный символ, который не может входить в число, завершает преобразование. Прототипы этих функций находятся в файле stdlib.h.


Содержание раздела