Элементарный ввод-вывод
Файл – это именованный объект, который может хранить данные, программу или любую информацию.
Поток – это последовательность байтов, которыми обмениваются различные устройства (файлы на диске, принтер, дисплей, клавиатура, стример и т.д.).
Файл – это может быть именованный объект данных, который следует по компьютерной сети, распечатка (листинг), данные на экране и т.д. Более того, часто подразумевается одно и то же, когда говорят о потоке и файле.
Функции ввода-вывода в языке С++ делятся на потоковыми и префиксные. Отличие. Потоковые функции осуществляют дополнительную буферизацию данных. Данные попадают в аппаратный буфер или файл (подразумеваем любой файл) через создаваемый этими функциями дополнительный буфер, т.е. участок памяти в ОЗУ.
Функции потокового файлового ввода-вывода описаны в заголовочном файле <stdio.h> – стандартный ввод-вывод.
Когда запускается любая программа на языке С++, операционная система открывает для нее (программы) стандартные потоки, в частности, имеющие имена stdin и stdout, под которыми подразумеваются соответственно клавиатура и экран монитора.
Таким образом, для ввода данные посылаются в поток с именем stdout, который донесет их до экрана монитора, а для ввода с клавиатуры – данные извлекаются из потока, который называется stdin. Иногда такой ввод-вывод называется консольным вводом-выводом. Консольный ввод-вывод бывает двух видов: неформатированный и форматированный.
Рис.1 Буферизованный выходной поток Рис. 2 Буферизованный входной поток
Форматированный ввод-вывод
Прежде мы уже пользовались форматированным вводом-выводом, который выполняется с помощью функций printf() и scanf(). Выражения, записываемые внутри скобок этих функций, называются аргументами.
Функция форматированного вывода printf( )
Функция форматированного вывода printf() имеет следующий синтаксис:
printf(форматная строка,аргумент_1,аргумент_2,…);
Форматная строка – последовательность символов, заключенная в двойные кавычки, в которой можно с помощью спецификаторов задавать способ преобразования данных.
Спецификаторы – это символы, которые начинаются знаком % . Вся форматная строка в функции printf() выдается на экран, причем спецификаторы %xxx заменяются значениями выводимых аргументов.
аргумент_1,аргумент_2,… – это переменная, константа или любое унарное выражение, которое может быть заключено в скобки. Например:
int a=2,b=5,c;
printf(“a=%d,b=%d,сумма=%d,c=%d\n”,а,b,a+b,9); //a=2,b=5,сумма=7,с=9
Количество спецификаторов должно совпадать с количеством выводимых переменных. Если число спецификаторов меньше количества переменных, то лишние переменные игнорируются. Если число спецификаторов больше количества переменных, то результат вывода не предсказуем.
Спецификаторы преобразования задается в виде:
%[флаги][ширина][.точность][l|L]<тип>
Имеются следующие типы преобразования переменных
%d %i – целое число типа int или char ;
%u – беззнаковое целое число unsigned int ;
%o – целое число типа int или char в 8-ой системе счисления;
%x – целое число типа int или char в 16-ой системе счисления;
%f – вещественное число типа float в виде целой и дробной части;
%e – вещественное число типа float в экспоненциальной форме;
%g – вещественное число в виде целой и дробной части или в экспоненциальной форме;
%c – целое число типа int или char в виде символа;
%s – строка;
%р – адрес переменной (&a).
Обратите внимание на модификаторы l и L .
Для переменных типа long int используются типы с модификатором %ld , %lo , %lu , %lx .
Для переменных типа double используются типы c модификатором %lf , %le , %lg .
Для переменных типа long double используются типы с модификатором %Lf , %Le , %Lg .
Ширина указывается в виде числа и определяет минимальное количество позиций, которые отводятся для вывода данных.
Если позиций недостаточно, то ширина игнорируется. Если их больше, чем выводимые данные, то пустые позиции дополняются пробелами. Например:
printf(“%5s”, ”дискета”); // дискета
printf(“%2d”, 400); // 400
printf(“%10s”,”дискета”); // дискета
printf(“%7d”, 400); // 400
Если в качестве значения ширины записать 0n , где n – число, определяющее ширину, то для целого числа позиции слева заполняются нулями.
printf(“%07d”, 400); // 0000400
Если ширину поля задать * , следующий аргумент функции (после форматной строки) будет определять ширину.
printf(“%*d”,5,10); // 5 – ширина поля, выведется 10
Точность задается для вещественных чисел и определяет, сколько знаков после десятичной точки из общей ширины поля будет напечатано. Ширина поля для вещественных чисел включает символы знака, точки, порядка.
printf(“%.0f”,5.47); // 5
printf(“%8.2f”,5.3334); // 5.33
printf(“%10.5f”,–5.33); // –5.33000
printf(“%.3e”,55.3334); // 5.533e+01
Если точность поля задать звездочкой * , следующий аргумент функции (после форматной строки) будет определять точность.
printf(“%6.*f”,2,7.1234); // точность 2, выведется 7.12
Если ширину поля и точность поля задать звездочками *.* , тогда второй аргумент функции будет определять ширину поля, а третий – точность.
printf(“%*.*f”,8,2,7.1234); // 7.12
Для строковой константы также распространяется понятие ширины и точности. Здесь под точностью понимаем количество выводимых символов из строки.
printf(“%8.3s”, “ABCDEF”); // ABC
Рассмотрим флаги .
– задает выравнивание числа влево. Справа будут пробелы.
printf(“%–6dkm”,30); // 30km
printf(“%–8.3sm”, “ABCDEF”); // ABCsm
+ задает вывод перед числом арифметического знака числа, т.е. перед числами будут печататься знаки + и – . Иначе печатается только – .
printf(“%+d”,300); // +300
printf(“%+d”,-300); // -300
пробел задает вывод перед положительным числом пробела.
printf(“%d”,300); // 300
printf(“%d”,–300); // –300
# определяет вывод идентификатора системы счисления (0 - для 8 СС, 0х - для 16 СС).
printf(“%#o”, 64); // 0100
printf(“%#х”, 50); // 0х32