Функции консольного ввода-вывода не используют входной буфер stdin для ввода данных. Все символы, вводимые с клавиатуры, доступны программе немедленно, что предоставляет дополнительные возможности при обработке данных в программе, при использовании директивы препроцессора:
#include<conio.h>
Функция ввода символа (без отображения):
getch ()
прочитывает код символа нажатой клавиши и не отображает символ на экране.
Это свойство можно использовать в двух случаях:
1. Для ввода невидимых символов в память и использования их для проверки пароля программы:
char ch; // описание символьной переменной
puts (“Нажмите любую символьную клавишу.”);
ch = getch(); // ввод кода символа без его отображения
// Символ и его код могут быть выведены на экран:
printf («\nСимвол: %c (код: %d)», ch, ch);
2. Для останова выполнения программы и просмотра текущих результатов на экране данных:
getch (); /* появляется экран данных */
puts (“После просмотра данных нажмите любую клавишу.”);
Функция ввода символа (с отображением):
|
|
getche ()
выполняет небуферизуемый ввод символа в отличие от функции getchar() и его отображение в отличие от функции getch().
Функция очистки экрана результатов:
clrscr ()
очищает экран данных от предыдущих сообщений и результатов. Эту функцию следует использовать в начале своей программы после описания переменных, а также в тех случаях, когда экрана данных не достаточно для вывода всех результатов и их приходится «листать».
Ввод-вывод данных в стиле С++
Ввод-вывод в С++, также как и в С, рассматривается как поток данных, управляемый с помощью функций ввода-вывода. В С++ для поддержки ввода-вывода данных используется целая иерархия классов. Двунаправленный поток поддерживается классом iostream, объявление которого помещено в заголовочный файл, подключаемый к программе строкой:
#include<iostream.h>
Стандартный ввод-вывод
С++ поддерживает два потоковых объекта для ввода/вывода:
1. cin – стандартный ввод, как правило, с клавиатуры (аналог stdin в С).
2. cout – стандартный вывод, как правило, на экран (аналог stdout в C).
Для каждого потока переопределены два оператора:
>>– оператор извлечения (чтения) из потока (для ввода с клавиатуры: "считать из");
<<– оператор записи (вставки) в поток (для вывода на экран: "вывести на").
Функции ввода/вывода способны воспринимать аргументы любых основных типов данных (char, char*(string), int, long, float, double).
Ввод для встроенных типов
Операция >> (извлечения, чтения) заменяет функцию ввода scanf() и лучше защищает от ошибок. Левый операнд – это объект cin. Правый операнд может быть любого типа, для которого определен ввод потока. По умолчанию оператор >> опускает пробельные символы, а затем считывает символы, соответствующие типу вводимого данного. Функции преобразования и форматирования данных зависят от их типов.
|
|
Для ввода-вывода можно строить цепочки операций слева направо. Например, так можно ввести несколько данных в С++:
int i; float f;
cin >> i >> f;
Для всех числовых типов в случае, когда первый непробельный символ не является цифрой, или знаком, или точкой (для вещественных чисел) поток входит в состояние ошибки и вплоть до сброса состояния ошибки любой дальнейший ввод запрещен.
Для целых типов short, int, long действие операции >> по умолчанию заключается в пропуске пробельных символов и преобразовании целого значения путем чтения символов ввода до символа, который не является допустимым для данного типа.
Для типов с плавающей точкой float иdouble действие операции >> состоит в пропуске пробельных символов и преобразовании значения с плавающей точкой до символа, который не может быть частью числа с плавающей точкой.
Вывод для встроенных типов
Операция <<, называемая вставкой, заменяет функцию вывода printf(). Левый операнд – это объект cout. Правый операнд может иметь любой тип, для которого определен вывод потоком для встроенных типов.
Функция-оператор << возвращает обращение по адресу, для которого она была вызвана, так что можно применить другой оператор <<, то есть можно строить цепочки операций вывода в порядке слева направо.
Например:
int i, k=234; double d; char ch='A';
cout<<”Значение k=” << k <<’\n’; // в конце символ перевода строки
cin>> i >> d; // ввод данных i, d
cout<<”i=”<< I <<” d=”<< d <<’\n’; // вывод значений i, d
cout<<”ch=”<< ch; // вывод символа A
Пример 5.
Потоки ввода-вывода.
#include<iostream.h> // подключение библиотек ввода-вывода
void main()
{ int i;
char str[ ]=”Пример вывода в С++\n”;
cout<<”Вывод строки”<< str;
cout<<”Введите целое и длинное целое число: “;
long l; // переменная описывается перед первым использованием
cin >> i >> l; // ввод данных
cout<<”i=” << ” l=” <<’\n;
cout<<”Введите строку: ”;
cin >> str;
cout << ”Введена строка: ”<<str;
}
Пример 6.
Встроенные типы вставок (вывода данных). Целые типы преобразуются по правилам (по умолчанию) для printf.
#include<iostream.h> // подключение библиотек ввода-вывода
#include<stdio.h> // для printf
#include<conio.h> // для консольных функций
void main()
{ int i=5; int *pi=&i; long l=12345678; double d=345.6789; char ch='A';
clrscr(); // чистка экрана результатов
cout<<”Вывод с помощью функции printf():\n”);
printf(“i=%d адрес i pi=%#x l=%ld d=%.4f ch=%c\n”, i,pi,l,d,ch);
cout<<”Вывод с помощью потока cout:\n”;
cout << ”i=”<< i << ” адрес i=” << &i << ” l =” << l << ” d=” <<d;
cout<<” ch=”<<ch<<'\n';
getch(); // задержка экрана результатов
}
Результаты программы:
Вывод с помощью функции printf():
i=5 адрес i pi=0xfff4 l=12345678 d=345.6789 ch=A
Вывод с помощью потока cout:
i=5 адрес i=0x8f61fff4 l=12345678 d=345.6789 ch=A
Управление вводом-выводом
Символьные извлечения.
Для типа char действие операции >> состоит в пропуске пробельных символов и чтения следующего (непробельного) символа. Если требуется прочесть следующий символ (любой), то можно использовать одну из функций-элементов get():
сhar ch;
cin.get(ch); // ch устанавливается на следующий символ потока, даже если это пробельный символ.
Следующий вариант get позволяет управлять числом извлекаемых символов, их размещением и оконечным символом:
get(char* buf, int max, int term=’\n’).
Эта функция считывает символы из входного потока в символьный массив buf до тех пор, пока не будет считано max -1символов, либо пока не встретится символ, заданный term, в зависимости от того, что будет раньше. Завершающий нуль-символ (‘\0’) добавляется автоматически. По умолчанию оконечным символом, который не требуется задавать, является ‘\n’. Сам оконечный символ в массив buf не считывается и из входного потока не удаляется. Массив buf должен иметь размер не менее max символов.
|
|
Пример 7.
Ввод строки цифр и преобразование их в целое число типа int с помощью функции atoi(s) и вывод числа в 10-ом, 16-ом, 8-ом форматах с использованием идентификаторов dec, hex, oct, вставленных в поток вывода для управления форматом выходного потока, endlаналог'\n'. (см. Манипуляторы).
#include<iostream.h> // подключение библиотек ввода-вывода
#include<conio.h> // для консольных функций
#include<stdlib.h> // для функции atoi()
const int size=35; // размер буфера строки
void main()
{ clrscr();
int value; // переменная для числа
char s [size]; // буфер строки
cout<<"Value= "; // ввод строки числа
value = atoi(s); // преобразование строки в число
cout<<"Decimal="<<dec<<value<<" Hexadecimal=0x"<<hex<<value
<<" Octal=0"<<oct<<value<<endl;
getch();
}
Результаты программы:
Value=123
Decimal=123 Hexadecimal=0x7b Octal=0173
Замечание. Для ввода строки вместо функции cin.get(s, size,'\n');можно использовать cin >> s ;. Этот оператор сработает, но если пользователь введет более 34 символов, оператор ввода продолжит запись за пределами буфера s, при этом, возможно, данные и код, располагающиеся за буфером, будут уничтожены. Такая операция может привести к краху системы!
Пример 8.
Использование функции get для безопасного чтения строк.
#include<iostream.h>
void main()
{ char s[35]; // буфер строки
char c; // переменная символа
cout<<"Введите строку не более 34 символов:\n";
cin.get(s, 35); // пропущен 3-й аргумент по умолчанию '\n'
cout<<"Вы ввели строку: "<<s<<endl;
if(cin.get(c) && c!='\n') // если следующий символ не '\n',то вывод
cout<<"Достигнута максимальная длина строки\n";
}
При вводе строки длиной более 34 символов она будет усечена, и ввод будет безопасным. Одна проблема все же остается. Символ '\n' или другой символ, завершающий ввод, остается в потоке и должен быть прочитан еще одним оператором cin.get(), как показано последним оператором if. Если cin.get()не читает символ '\n',ввод будет усечен. Этот факт необходимо учитывать при написании программ.
|
|
Проблему непрочитанного символа '\n' можно решить с помощью метода cin.getline()с тремя параметрами (совпадет с get()), при этом символ разделитель '\n' также помещается в принимающую строку символов (s).
Форматирование ввода/вывода
Форматирование ввода и вывода определяется флагами состояния формата. Их можно изменить с помощью специальных функций.
Ширина вывода.
По умолчанию вставки выводят минимальное число символов, которыми может быть представлен операнд правой части. Для изменения используются функции:
int width(int w); // устанавливает поле шириной w символов и возвращает предыдущую ширину,
int width(); // возвращает предыдущую ширину, не внося изменений.
По умолчанию width=0, т.е. вывод выполняется без заполнителей. При w≠0, если длина числа меньше w используются заполнители, иначе выводится фактическое число без усечения.
Например:
int i=123;
int oldw=cout.width(6);
cout << i; // вывод будет 123 (перед числом 3 пробела), затем width=0
cout.width(oldw); // восстановление предыдущей ширины width=6
После каждой форматной вставки ширина обнуляется, например:
int i, j;
cout.width(4);
cout << i <<" "<< j <<;
Здесь i будет выведено четырьмя символами, однако пробел и j будут иметь минимально необходимое число символов.
Заполнители и дополнение вправо и влево.
Символ-заполнитель и направление дополнения зависят от установок внутренних флагов, отвечающих за эти параметры.
По умолчанию символом-заполнителем является пробел. Изменить данное умолчание позволяет функция fill:
int i=123;
cout.fill ("*");
cout.width(6);
cout<< i; // на экран будет выведено ***123
По умолчанию устанавливается выравнивание по правому краю (дополнение символами-заполнителями). Это можно изменить функциями setf и unsetf:
int i=56;
cout.width(6);
cout.fill ("#");
cout.setf (ios::left, ios::adjustfield);
cout<< i; // на экране: 56####
Второй аргумент сообщает setf, какие биты флага должны быть установлены. Первый аргумент сообщает, в какие именно значения устанавливаются эти биты.
Можно также использовать манипуляторы setfill, setiosflags, resetiosflags.
Манипуляторы.
Это специальные операции (похожие на функции) для более простого изменения ширины и других параметров форматирования. Для их использования программа должна иметь строку:
#include<iomanip.h>
Манипуляторы принимают в качестве аргумента ссылку на поток и возвращают ссылку на тот же поток. Поэтому манипуляторы могут объединяться в цепочку вставок (или извлечений из потока) для того, чтобы изменять состояние потока в виде побочного эффекта, без фактического выполнения каких-либо вставок или извлечений.
Пример 9.
Применение функций и манипуляторов форматирования вывода в программе.
#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
void main()
{ clrscr();
int i=36, j=45;
cout<<"Вывод с установленной шириной поля 5 числа i:\n";
int oldw=cout.width(5); // установка ширины поля вывода
cout<< i <<'\n';
cout<<"После каждой вставки формата ширина поля=0:\n";
cout<< " oldw=" << oldw << '\n';
cout<< i << '\n';
cout<< "Установка поля 5 влияет только на 1-ю переменную:\n";
cout.width(5);
cout<< i << " " << j << '\n';
cout<< "Манипулятор setw(5) упрощает вывод переменных:\n";
cout<< setw(5) << i << setw(5) << j << '\n';
cout<< "Манипуляторы dec, hex, oct изменяют сист. счисл. \n";
cout<< "(оставляя эти изменения в силе) — вывод i:\n";
cout<< dec << i << " " << hex << i << " " << oct << i <<endl;
cout<< "Манипулятор endl аналог '\n' очищает поток"<<endl;
cout<< "i= " << i <<endl;
cout<< "Заполнитель пробел можно заменить на *"<<endl;
cout.fill ('*'); // задание символа заполнения функцией fill
cout<< setw(6) << i << endl; // установка ширины поля 6 числа i
cout<< "Выравнивание можно изменить функцией setf:"<<endl;
cout.width(6);
cout.setf(ios::left, ios::adjustfield);
cout<< "i = " << i <<endl;
getch();
}
Вывод чисел с плавающей точкой.
Большие и малые числа выводятся в экспоненциальном формате (е, Е), а не фиксированном. Например, число 1234567.8 печатается 1.2345678Е+07.
Числа с нулевой дробной частью печатаются как целые. Например, число 95.0 печатается 95.
Для вывода десятичных чисел в фиксированном формате можно использовать следующие операторы:
cout.setf(ios::fixed, ios::floated);
cout.setf(ios::showpoint);
Первый вызов функции setf обеспечивает печать чисел в фиксированном, а не экспоненциальном представлении. Второй вызов задает печать десятичной точки, даже если дробная часть числа равна 0.
Управление числом десятичных позиций при выводе выполняется с помощью манипулятора установки точности:
cout<< setprecision(2) << x;
например, вместо числа 16.38567 печатается 16.39.
Структура программы С/С++
Программа на языке высокого уровня представляет собой формализованный текст, включающий описательные предложения для представления объектов программы и исполняемые предложения (операторы), реализующие алгоритм задачи. Далее программы на С/С++ для простоты будем называть С-программами.
С-программа оформляется в виде одной или нескольких подпрограмм (вспомогательных программных единиц), называемых функциями. При этом только одна функция является обязательной и за ней закреплено имя main (главная, основная), поскольку с нее начинается выполнение программы. Простая С-программа является описанием главной функции, которое включает заголовок функции и тело функции, заключенное в операторные скобки { } и называемое блоком:
тип main (параметры) // заголовок функции
{ // блок – тело функции:
описательная часть; // описания данных
исполняемая часть; // операторы
}, где
тип – ключевое слово типа, для возвращаемого функцией значения, либо void (отсутствие типа), если значение не возвращается;
параметры – необязательный список формальных параметров с их типами, но даже если он пустой, наличие круглых скобок для функции обязательно.
Тело функции (блок) включает описания данных (объектов программы) и последовательность исполняемых операторов, определяющих действия функции. Описания данных и операторы должны заканчиваться разделителем точка с запятой (;). Блоки могут быть вложенными, однако сами функции вложенными быть не могут.
Исходная С-программа набирается и редактируется в программной среде как текстовый файл, который может содержать дополнительные части и должен сохраняться во внешней памяти с собственным именем и расширением “.cpp” в студенческом каталоге группы по правилам файловой системы компьютера, например, D:\$STUDENT\GR_1006\myprog.cpp.