Средства ввода-вывода языка C/C++ Форматированный вывод на консоль • printf(строка_формата, аргумент1, аргумент2, …, аргументN) • // Простой случай (без аргументов) • printf(“Hello, world!\n”); • // Сложный случай (с аргументами) • int a=2, b=3; • int sum=a+b; • printf(“%d=%d+%d”, sum, a, b); Обработка строки формата • В обычном случае строка формата просто выводится на экран • Модификаторы формата, начинающиеся с символа %, заменяются очередным аргументом • В модификаторах формата задается предполагаемый тип аргумента (фактически он не проверяется) и способ его вывода Пример программы, использующей функции ввода/вывода в стиле С: #include <stdio.h> int main() { int i: printf("Введите целое число\п"); scanf(“%d", &i); printf("Вы ввели число %d, спасибо!", i); return 0: } А вот как выглядит та же программа с использованием библиотеки классов C++: #include <iostream.h> int main() { int 1: cout << "Введите целое число\п"; cin >> 1; cout << "Вы ввели число " << i << ". спасибо!"; return 0; } Простые модификаторы формата • %c - подстановка char • %d или %i - подстановка int – %o - то же в восьмеричной системе – %x - то же в шестнадцатеричной системе • %u - подстановка unsigned • %f, %lf - подстановка float, double в обычной форме – аналог cout<<fixed • %e, %le - то же в экспоненциальной форме – аналог cout<<scientific • %g, %lg - то же в форме, занимающей меньше места • %s - подстановка строки (char*) • %% - вывод символа % (не является модификатором формата, так как не приводит к чтению аргумента) Сложные модификаторы формата (целые, вещественные) • Все сложные модификаторы формата влияют только на вывод одной переменной (в отличие от манипуляторов для cout<<) • %5d - вывод целого числа в 5 позициях – аналог cout<<setw(5) • %05d - вывод целого числа в 5 позициях с нулями впереди – аналог cout<<setfill(‘0’)<<setw(5) • %9.3lf - вывод вещественного числа (double) в 9 позициях с 3 знаками после десятичной точки – аналог cout<<setw(9)<<setprecision(3) • %+5d или %+9.3lf - вывод числа со знаком (+ или -) впереди – аналог cout<<showpos • %-5d - вывод числа с выравниванием влево (число слева, пробелы справа) – аналог cout<<left • по умолчанию все выравнивается вправо Сложные модификаторы формата (строки) • %20s - вывод строки в 20 позициях (по умолчанию строка выравнивается вправо, слева вставляются пробелы) • %-20s - вывод строки в 20 позициях с выравниванием влево • %.5s - вывод первых 5 символов строки • %20.5s - вывод первых 5 символов строки в 20 позициях Пример // Переменная currTime содержит время // в минутах, необходимо вывести hh:mm // С помощью cout // Для тех, кто не понял: minInHour = 60 • cout<<setfill(‘0’); • cout<<setw(2)<<currTime/minInHour<<":"; • cout<<setw(2)<<currTime%minInHour; // С помощью printf • printf(“%02d:%02d”, currTime/minInHour, currTime%minInHour); Форматированный ввод с клавиатуры • scanf(строка_формата, аргумент1, аргумент2, …, аргументN) • Результат функции - число успешно прочитанных аргументов • Для целых, вещественных, символьных аргументов используются адреса (&a, &f, &c) • // Например • int a, b; • scanf(“%d%d”, &a, &b); • Для строк используется адрес первого элемента (или имя массива) • // Например • char str[20]; • // Если пользователь введет 20 и более символов, • // то произойдет ошибка • scanf(“%s”, str); • // или (запись в массив начиная с 5-го элемента) • scanf(“%s”, &(str[5]); Анализ строки формата • Символы - не модификаторы формата ожидаются во вводимой строке • Простые модификаторы формата те же, что для printf (%c, %d, %i, %o, %x, %f, %lf, %e, %le, %g, %lg, %s) • %20s - ввод не более 20 символов строки (безопасно, в отличие от %s) • %3d - ввод целого числа не более 3 цифр • %*lf - прочитать вещественное число, но не записывать в очередной аргумент Достоинства <stdio.h> • printf и scanf присутствуют и в реализациях чистого C, и в реализациях C++; cout<< и cin>> присутствуют только в реализациях C++ • В случаях, когда необходим сложный форматированный ввод/вывод, с помощью scanf/printf запись получается более компактной • В целом, число возможностей scanf/printf несколько больше (см. также MSDN) Недостатки <stdio.h> • printf и scanf не контролируют типы аргументов; если тип аргумента не соответствует ожидаемому, в лучшем случае произойдет ошибка, а в худшем произойдет ввод или вывод не той информации, которую ожидает программист • printf и scanf не могут выводить переменные пользовательских типов; с помощью cout<< и cin>> это возможно • На взгляд системных программистов, ввод-вывод с помощью cin>> и cout<< нагляднее и проще в освоении Лабораторные задания В программе необходимо выполнить ввод и вывод данных различных типов: -ввод символа и его вывод в символьном виде и в виде кода (формат %с); -ввод строки символов (длина не менее 15 символов), и вывод строки символов (формат %s); -ввод двух целых десятичных чисел (положительного и отрицательного) и их вывод в десятичном (формат %d) и шестнадцатеричном виде; -ввод двух чисел с плавающей точкой (положительного и отрицательного) и их вывод в десятичной (формат %f) и экспоненциальной (формат %e) формах с заданной точностью (не менее трех знаков после десятичной точки); -ввод целого беззнакового числа и его вывод в виде десятичного целого без знака (формат %u), восьмеричного целого без знака (формат %o), шестнадцатеричного целого без знака (формат %x). Варианты лабораторных заданий Выполнить ввод и вывод переменных заданных типов: 1. ’A’; ’Меня зовут <фамилия и имя>’; 315,-27; 127.361, -574.953; 2124. 2. ’B’; ’Меня зовут <фамилия и имя>’; 789,-76; 956.361, -395.659; 794. 3. ’C’; ’Меня зовут <фамилия и имя>’; 873,-846; 52.471, -426.638; 537. 4. ’D’; ’Меня зовут <фамилия и имя>’; 191,-437; 138.76, -961.753; 993. 5. ’E’; ’Меня зовут <фамилия и имя>’; 727,-968; 374.652, -776.23; 108. 6. ’F’; ’Меня зовут <фамилия и имя>’; 356,-592; 1761.98,-394.152; 206. 7. ’G’; ’Меня зовут <фамилия и имя>’; 735,-692; 309.54, -276.372; 489. 8. ’H’; ’Меня зовут <фамилия и имя>’; 896,-372; 682.471,-367.596; 792. 9. ’I’; ’Меня зовут <фамилия и имя>’; 694,-785; 579.851,-468.341; 689. 10. ’J’; ’Меня зовут <фамилия и имя>’; 573,-942; 358.904,-357.986; 468. 11. ’K’; ’Меня зовут <фамилия и имя>’; 426, -794; 246.57,-135.79; 357. 12. ’L’; ’Меня зовут <фамилия и имя>’; 135,-462; 324.56,-236.745; 579. 13. ’M’; ’Меня зовут <фамилия и имя>’; 243,-157; 58.362,-416.68; 362. 14. ’N’; ’Меня зовут <фамилия и имя>’; 642,-357; 369.42,-247.57; 429. 15. ’P’; ’Меня зовут <фамилия и имя>’; 963,-785; 426.37,-653.871; 643.