Для организации ввода-вывода в программе на языке C++ используется подключаемый файл iostream.h, который содержит определение нескольких классов и объектов, обеспечивающих методы ввода-вывода. В частности, язык C++ поддерживает четыре предопределенных объекта, выполняющих ввод-вывод:
1) cout – стандартный вывод, соответствующий stdout в языке С (обычно дисплей);
2) cin – стандартный ввод, соответствующий stdin в языке С (обычно клавиатура);
3) cerr – стандартный вывод ошибок, соответствующий stderr в языке С;
4) clog – буферизованная версия cerr (нет эквивалента в языке С).
Эти стандартные потоки можно переназначать на другие устройства или в файлы.
Объект cout является объектом класса ostream. Этот класс используется для управления форматированным и неформатированным выводом. Здесь определяется операция << для обработки вывода встроенных типов. Например:
class ostream
{
…
public:
inline ostream& operator<<(ostream& (__cdecl * _f)(ostream&));
inline ostream& operator<<(ios& (__cdecl * _f)(ios&));
ostream& operator<<(const char *);
inline ostream& operator<<(const unsigned char *);
inline ostream& operator<<(const signed char *);
inline ostream& operator<<(char);
ostream& operator<<(unsigned char);
inline ostream& operator<<(signed char);
ostream& operator<<(short);
ostream& operator<<(unsigned short);
ostream& operator<<(int);
ostream& operator<<(unsigned int);
ostream& operator<<(long);
ostream& operator<<(unsigned long);
inline ostream& operator<<(float);
ostream& operator<<(double);
ostream& operator<<(long double);
ostream& operator<<(const void *);
ostream& operator<<(streambuf*);
……
};
Таким образом, оператор cout << x посылает значение переменной х в объект cout класса ostream для вывода. Функция operator << возвращает ссылку на объект ostream, для которого она была вызвана. Поэтому к результату операции вывода можно еще раз применить операцию вывода, т.е. несколько операций вывода можно сцепить. Например:
int х=5;
cout << "х = " << х << "n";
В зависимости от типа переданного аргумента будет вызываться тот или иной экземпляр функции operator <<.
Для вывода двоичных данных полезными могут оказаться функции put и write, объявленные в классе ostream. Например:
inline ostream& put(char);
ostream& put(unsigned char);
inline ostream& put(signed char);
ostream& write(const char *,int);
inline ostream& write(const unsigned char *,int);
inline ostream& write(const signed char *,int);
Функция put() записывает единственный символ в поток ostream, тогда как функция write() передает заданное число байтов.
Поскольку функции put() и write() возвращают ссылку на объект выводного класса, то они также могут быть сцеплены.
Аналогично выводу в языке C++ определяется и ввод. С вводом связан класс istream, в котором определена перегруженная операция >> для стандартных типов:
class istream {
…
public:
inline istream& operator>>(istream& (__cdecl * _f)(istream&));
inline istream& operator>>(ios& (__cdecl * _f)(ios&));
istream& operator>>(char *);
inline istream& operator>>(unsigned char *);
inline istream& operator>>(signed char *);
istream& operator>>(char &);
inline istream& operator>>(unsigned char &);
inline istream& operator>>(signed char &);
istream& operator>>(short &);
istream& operator>>(unsigned short &);
istream& operator>>(int &);
istream& operator>>(unsigned int &);
istream& operator>>(long &);
istream& operator>>(unsigned long &);
istream& operator>>(float &);
istream& operator>>(double &);
istream& operator>>(long double &);
istream& operator>>(streambuf*);
};
Объект cin класса istream используется для ввода с назначенного устройства. Например:
int х;
cin >> х;
В зависимости от того, как объявлена переменная х, в область памяти, именуемую х, вводится целое, плавающее число, символ или строка символов.
Функция operator >> возвращает ссылку на определенный объект класса istream, значит, операции ввода можно связывать в цепочку. Например:
cin >> х >> d >> с;
Вводимые значения должны соответствовать объявленному типу и должны разделяться пробелом. В качестве альтернативы можно использовать набор перегружаемых функций get() и read():
class istream
{
int get();
inline istream& get( char *,int,char =’n’);
inline istream& get(unsigned char *,int,char =’n’);
inline istream& get( signed char *,int,char =’n’);
istream& get(char &);
inline istream& get(unsigned char &);
inline istream& get( signed char &);
istream& get(streambuf&,char =’n’);
inline istream& getline( char *,int,char =’n’);
inline istream& getline(unsigned char *,int,char =’n’);
inline istream& getline( signed char *,int,char =’n’);
istream& read(char *,int);
inline istream& read(unsigned char *,int);
inline istream& read(signed char *,int);
istream& putback(char);
int peek();
inline istream& ignore(int =1,int =EOF);
};
Используя эти функции, можно ввести любые символы, в том числе и пробельные. Например, функция get (char &) просто читает один символ и помещает его в свой аргумент. Другая функция get() из набора перегружаемых функций может выполнить более сложную работу. Она читает и размещает по адресу, заданному первым аргументом, не более символов, чем задано вторым аргументом.
По умолчанию функция get() прочтет не более чем n символов и не более чем одну строку. Последнее ограничение определяется третьим аргументом – он задает символ-ограничитель, по прочтении которого функция прекращает работу. По умолчанию таким символом-ограничителем является ‘n’. Но пользователь может его переустановить, задав при вызове функции три аргумента. Этот символ-ограничитель остается во входном потоке и будет первым символом для чтения при выполнении следующей операции чтения, если его оттуда не удалить каким-либо способом. Например:
char buffer[512];
cin.get(buffer, 512, ‘v‘);
Функция get() будет читать в buffer не более 512 символов, но если среди символов встретится символ вертикальной табуляции (v), то функция прекратит работу. В этом случае первым символом, который будет прочитан из cin следующей операцией чтения, будет символ ‘v’. Заметим, что функции get возвращают ссылку на объект класса istream, для которого они были вызваны. Значит, они могут быть сцеплены в цепочку. Например:
char str[10];
char ch, ph;
cin.get(ch).get(str).get(ph);
В переменные ch, str и ph из потока cin будут введены значения.
При организации ввода-вывода полезными могут оказаться еще несколько функций:
· функция putback(char с) возвращает символ обратно в поток iostream;
· функция peek () возвращает следующий символ (или EOF), но не удаляет его из потока;
· функция ignore (int Limit = 1, int Delim = EOF) пропускает указанное количество символов и останавливается, если встречает символ Delim. По умолчанию, если никакие аргументы не заданы, функция ignore() пропускает один символ и останавливается, если встречает конец файла.