Смекни!
smekni.com

Основы алгоритмического языка С++ (стр. 13 из 21)

% [flags] [width] [.precision] [F | N | h | l | L ] <символ типа>

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

Таблица 7.2. Значения флагов строки формата функции printf

Символ Назначение
- Выравнивать вывод по левому краю поля
+ Всегда выводить знак числа
Пробел Выводить пробел перед положительным числом и знак минус — перед отрицательным
# Не влияет на вывод десятичных целых, для шестнадцатеричных чисел выводит префикс 0х или 0Х, перед восьмеричными целыми выводит ноль, десятичную точку для вещественных чисел.

Спецификация width определяет минимальное количество выводимых символов. Если необходимо, используются заполнители — пробелы или нули. Когда значение для width начинается с нуля, printf использует в качестве заполнителей нули, а не пробелы. Если в качестве значения для width используется универсальный символ *, а не число, то printf подставляет на место этого символа значение, которое должно содержаться в списке аргументов. Это значение ширины поля должно предшествовать выводимому значению. Ниже приведен пример вывода числа 2, занимающего три позиции, согласно значению второго аргумента printf:

printf("%*d", 3, 2);

Спецификатор precision определяет максимальное количество выводимых цифр. В случае целого числа он определяет минимальное количество выводимых символов. Для precision также можно применить символ *, вместо которого будет подставлено значение из списка аргументов. Это значение точности представления должно предшествовать выводимому значению. Ниже приведен пример вывода числа с плавающей точкой 3.3244 с использованием десяти символов, как это задано вторым аргументом printf:

printf("%7.*f", 10, 3.3244);

Символы F, N, h,l и L являются символами размера, переопределяющими размер по умолчанию. Символы F и N применяются с указателями, far и near соответственно. Символы h, l, и L используются для указания соответственно типов short int, long или long double.

Символам типа данных должен предшествовать форматирующий символ %. В таблице 7.2 мы показали возможные значения флагов форматирующей строки printf. Символы типов данных перечислены в таблице 7.3.

Таблица 3. Символы типов данных строки формата функции printf

Тип данных символ типа результат
Символ c Один символ
d Десятичное целое со знаком
i Десятичное целое со знаком
O Восьмеричное целое без знака
N Десятичное целое без знака
X Шестнадцатеричное целое без знака; набор цифр - 0123456789abcdef
X Шестнадцатеричное целое без знака; набор цифр - 0123456789ABCDEF
Указатель P Для указателей near выводит только смещение в виде: 0000. Указатели far отображаются в виде: SSSS:0000
Указательна целое N
Вещественное F Выводит величину со знаком в формате [-]dddd.dddd
E Выводит вещественную величину со знаком в экспоненциальном формате [-]d.dddde[+|-]ddd
Е Выводит вещественную величину со знаком в экспоненциальном формате [-]d.ddddE[+|-]ddd
G Выводит вещественную величину со знаком в формате f или е в зависимости от ее значения и заданной точности
G Выводит вещественную величину со знаком в формате F или Е в зависимости от ее значения и заданной точности
Указатель S Выводит строку символов, пока не встретит нуль-терминатор строки

Разберем небольшой пример. Программа OUT2.CPP, исходный код которой приведен в листинге 3, создана на основе программы OUT1.CPP. В этой программе используется форматированный вывод с использованием функции printf. Программа выводит те же числа, что и OUT1.CPP, используя три различных набора спецификаций преобразования.

Листинг 3. Исходный текст программы OUT2.CPP в файле List7-3.CPP

01 // Программа, использующая printf для форматирования вывода
02
03 #include <stdio.h>
04
05 int main()
06 {
07 int anInt = 67;
08 Unsigned char aByte = 128;
09 char aChar = '@';
10 Float aSingle = 355.0;
11 Double aDouble = 1.130e+002;
12
13 Printf("%3d + %2d = %3d&bsol;n",
14 aByte, anInt, aByte + anInt );
15
16 Printf("Вывод использует спецификации преобразования %%lf :&bsol;n");
17 Printf(" %6.4f / %10.4lf = %7.5lf&bsol;n",
18 aSingle, aDouble, aSingle / aDouble );
19
20 Printf("Вывод использует спецификации преобразования %%le :&bsol;n");
21 printf(" %6.4e / %6.4le = %7.5le&bsol;n",
22 aSingle, aDouble, aSingle / aDouble );
23
24 printf("Вывод использует спецификации преобразования %%lg :&bsol;n");
25 printf(" %6.4g / %6.4lg = %7.5lg&bsol;n",
26 aSingle, aDouble, aSingle / aDouble );
27
28 printf("Символьная переменная aChar: %c&bsol;n", aChar);
29 printf("ASCII-код %c: %d&bsol;n", aChar, aChar);
30 return 0;
31 }

Пример вывода программы из листинга 3:

128 + 67 = 195

Вывод использует спецификации преобразования %lf :

355.0000 / 113.0000 = 3.14159

Вывод использует спецификации преобразования %le :

3.5500e+02 / 1.1300e+02 = 3.14159e+00

Вывод использует спецификации преобразования %lg :

355 / 113 = 3.1416

Символьная переменная aChar: @

ASCII-код @: 64

В программе из листинга 3 объявляется целый набор переменных различных типов. Оператор вывода в строках 13 и 14 выводит целые, используя спецификацию формата %d. В таблице 4 приведены результаты действия спецификаций преобразования из строки 13. Обратите внимание на то, что первая переменная была преобразована из типа unsigned char в тип integer.

Таблица 4. Результат действия спецификаций форматирования в функции printf из строки 13

Спецификация формата Переменная Тип данных Тип после преобразования
%3d aByte unsigned char Int
%2d anInt int Int
%3d aByte + anInt int Int

Оператор вывода в строке 17 выводит переменные aSingle, aDouble и выражение aSingle / aDouble, используя спецификации преобразования %6.4f, %6.41f и % 7.51f. Точность представления задается ими равной 4, 4 и 5 цифрам, а минимальная ширина поля 6, 6 и 7 цифрам соответственно. Две последних спецификации осуществляют преобразование величин двойной точности.

Оператор вывода в строке 21 подобен оператору из строки 17. Отличие состоит в том, что используется е-формат вместо f-формата. Соответственно три значения выводятся в экспоненциальном формате.

Оператор из строки 25 также похож на оператор из строки 17. Основное отличие состоит в том, что вместо f-формата используется g-формат. В результате первые два числа выводятся без дробной части, поскольку они являются целыми величинами.

Оператор вывода в строке 28 выводит содержимое переменной aChar по формату %с. Оператор вывода в строке 29 выводит ту же переменную aChar дважды, первый раз как символ, а второй раз как целое (или, если быть точным, выводится ASCII-код символа). Для этого используются спецификации преобразования %с и %d соответственно.

Массивы символов в C++

В C++ имеется специальный класс для работы со строками, которого, конечно, не было в языке С. В С строки вводились как массивы символов, ограниченные нуль-символом (ASCII-код которого равен нулю), поэтому большое количество программ, написанных на С, используют символьные массивы. Более того, и в C++, несмотря на то, что он имеет класс для работы со строками, находится применение массивам символов. Поэтому термин “строка” имеет два значения: строка в смысле C++ и строка как массив символов. Весь этот раздел будет посвящен тому, как нужно и не нужно использовать символьные массивы.

Символ '&bsol;0' также называют нуль-терминатором. Строки, оканчивающиеся нуль-терминатором, называют еще ASCIIZ-строками, гдесимвол Z обозначает ноль — ASCII-код нуль-терминатора. Еще этот символ называют NUL-символом, поскольку этот термин является его именем в ASCII.

Все строки обязательно должны оканчиваться нуль-терминатором, и при объявлении размера массива необходимо это учитывать. Когда вы объявляете строковую переменную как массив символов, увеличьте размер массива на один символ для нуль-терминатора. Использование строк с конечным нулем также имеет то преимущество, что здесь отсутствуют ограничения, накладываемые реализацией C++. Кроме того, структура ASCIIZ-строк очень проста.

Ввод строк

В программах, которые мы рассматривали, операторы потокового вывода выводили строковые константы; C++ поддерживает потоковый вывод для строк как специального не-предопределенного типа данных. (Можно сказать, что это было сделано по требованию масс.) Операции и синтаксис для вывода строковых переменных остаются прежними. При вводе строк операция извлечения из потока ” не всегда будет работать так, как вы ожидаете, поскольку строки часто содержат пробелы, которые игнорируются оператором ввода; поэтому вместо оператора ввода вам нужно использовать функцию getline. Эта функция вводит заданное количество символов.