- Стандартный поток ввода (обозначение: stdin , cin и др.) - используется для ввода символьных данных в программу. По-умолчанию этот поток закреплён за клавиатурой компьютера;
- Стандартный поток вывода (обозначается как: stdout , cout и др.) - используется для вывода символьной информации, полученной в результате работы программы в "штатном режиме". По-умолчанию этот поток закреплён за экраном дисплея;
- Стандартный поток ошибок (обозначение: stderr
, cerr
и др.) - используется для вывода символьных диагностических сообщений
, ошибок и предупреждений, возникших в результате работы программы. По-умолчанию этот поток закреплён за экраном дисплея;
Примечание: стандартный поток и поток ошибок разделены в связи с тем, что при перенаправлении вывода часто совсем не нужно записывать в результаты работы программы диагностические сообщения. Эти сообщения будут лишними, например, при формировании таблицы базы данных в виде текстового файла;
- Стандартный поток печати (обозначение: stdprn и др.) - используется для вывода результатов работы программы на печать. По-умолчанию этот поток закреплён за текущим принтером в системе, подключённым к порту LPT1 . В настоящее время этот поток почти не используется, поскольку чаще проще и безопаснее перенаправить стандартный поток вывода на принтер, чем разделять потоки отдельно для экрана и отдельно для принтера.
Все остальные потоки создаются или уничтожаются с помощью функций открытия и закрытия файлов, на период чтения/записи/добавления информации в эти файлы.
6.2. Ввод со стандартного потока ввода 6.2.1. Ввод средствами языка СиВвод со стандартного потока в Си осуществляется при помощи следующих функций:
- для ввода одиночного символа - функцию getchar ;
- для ввода строки символов без ограничения на длину - функцию gets ;
- для "форматированного ввода" символов и их преобразования в "двоичные значения" переменных - функцию scanf ;
С синтаксисом и правилами использования этих функций можно ознакомиться в приложении №I к данной лекции. Автор хочет отметить, что использование функций ввода со стандартного потока является небезопасным, а, следовательно, и нежелательным способом ввода данных из стандартного потока. По возможности, заменяйте эти функции функциями потокового чтения данных с "явным" указанием потоков и "длины" прочтённой строки.
Пример 6.1
/* Файл ex06001.c */ /* Функция иллюстрирует потоковый ввод-вывод (как это делать нельзя)*/ #include #define STR_LENGTH 3 // Длина строки 3 символа void main() { char str; // Текстовый буфер char *s; // Временная переменна s = gets(str); puts(s); }
Например, функция, приведённая в примере 6.1, при вводе строки: "aaaaaaaa\n" , - вызовет аварийное завершение с ошибкой "переполнение буфера". Поскольку длина текстового буфера - 2 символа (последний символ - "нулевой", знак окончания строки "\0" ), то лишние символы, введённые с клавиатуры, попадают в "запредельную" системную область данных. В этом случае происходит операция (прерывание) "отказ системы", и адрес этой системной области оказывается доступной "взломщику системы". Функции, приведённые в примерах 6.2 и 6.3, лишены этих недостатков;
Пример 6.2
/* Файл ex06002.c */ /* Функция иллюстрирует потоковый ввод-вывод (как это делать надо)*/ /* Пример тестировался в системе программировани Borland C/C++ 3.10 */ #include #include #define BUF_LENGTH 7 // Длина строки 3 символа #define STR_LENGTH 2 // Длина буфера без дескриптора // Всё те же 2 символа void main() { char str; // Текстовый буфер char *s, c = "\0"; // Временная переменная. int icsize; // Временная переменная. icsize = BUF_LENGTH - 2; str = (char) icsize; s = cgets(str); puts(s); puts("\nPress any key to continue..."); while(!(c = getch())); // Цикл пока не нажата клавиша }
Пример 6.3
/* Файл ex06003.c */ /* Функция иллюстрирует потоковый ввод-вывод (как это делать надо)*/ /* Пример тестировался в системе программировани Borland C/C++ 3.10 */ #include #include #include #define STR_LENGTH 3 // Длина строки 3 символа void main() { char str; // Текстовый буфер char *s, c = "\0"; // Временная переменная. int icsize; // Временная переменная. memset(str, "\0", STR_LENGTH); // Обнуляем буфер icsize = STR_LENGTH; s = fgets(str, icsize, stdin); // Читаем не более 2 символов с входного потока // (вместе с нулевым символом) puts(s); puts("\nPress any key to continue..."); while(!(c = getch())); // Цикл пока не нажата клавиша }
6.2.2. Ввод средствами языка C++Консольный потоковый ввод в языке C++ осуществляется при помощи операторов ">>" , а также при помощи функций get , peek и ignore . Стандартный поток ввода в языке C++ обозначается как cin (см. таблицу 6.1).
Значение дескриптора | 0 | 1 | 2 | 3 | 4 |
Обозначение в Си | stdin | stdout | stderr | stdaux | stdprn |
Обозначение в C++ | cin | cout | cerr | нет | нет |
Обозначение в Java | System.in | System.out | ? | нет | нет |
Обозначение в Perl | STDIN | STDOUT | STDERR | нет | нет |
Обозначение в Python | sys.stdin | sys.stdout | sys.stderr | нет | нет |
Обозначение в VBScript | StdIn | StdOut | StdErr | нет | нет |
Описание функций для потокового ввода средствами языка C++ смотри в приложении №III к данной лекции.
C помощью оператора ">>" можно осуществить как неформатированный, так и форматированный ввод-вывод. Однако автор советует для ввода использовать неформатированный ввод из потока с помощью функции cin.get , а затем "выделить и ввести" нужные двоичные значения при помощи функции sscanf (см. пример 6.4.).
Пример 06.004 .
/* File ex06004.cpp */
/* Пример ввода-вывода средствами C++*/
/* Пример тестировался в системе программировани
Borland C/C++ 3.10 */
#include
#include
#include
#include
#ifndef STR_LENGTH
#define STR_LENGTH 35 // Длина строки 34 символа + завершающий символ "\0"
#endif
#ifndef INT_WIDTH
#define INT_WIDTH 5 // Ширина под поле целого числа - 4 символов
#endif
void main(void)
{
const char format_in = "%5d"; // Формат ввода
const char format_out = "\nВведённое значение: %5d"; // Формат вывода
char str, c="\0";
int iValue;
(void) memset(str, "\0", STR_LENGTH); // Обнуляем строку;
cout