Читайте также: |
|
Ошибки ввода/вывода потоком устанавливает соответствующий биты.
Бит состояния | Его смысл |
goodbit | Если этот бит не установлен, то все в порядке |
eofbit | "Конец файла": устанавливается, если istream не имеет больше битов для извлечения. Последующие попытки выполнить извлечение игнорируются. |
failbit | Устанавливается, если последняя операции ввода/вывода окончилась неудачей. После сброса данного бита ошибки поток готов к последующему использованию. |
badbit | Устанавливается, если последняя попытка ввода/вывода являлась недопустимой. |
hardfail | Устанавливается, если для данного потока встретилось невосстановимое состояние ошибки. |
После того, как поток получил состояние ошибки, все попытки вставки или извлечения из данного потока будут игнорироваться до тех пор, пока не будет исправлено условие, вызвавшее состояние ошибки, а бит(ы) ошибки очищен(ы) (при помощи, например, функции компонента ios::clear(i).
Резидентные потоки применяются для выполнения форматных операций ввода/вывода для данных, находящихся в памяти. В файле strstream.h определены три класса резидентных потоков: istrstream, ostrstream и strstream. Создавая резидентный поток, нужно указать буфер и его размер. Если буфер ввода
заканчивается символом '\0', то размер буфера указывать не обязательно. При записи в буфер вывода в конце нужно добавить символ '\0' для правильной работы метода ostrstream::str.
Если при создании выходного резидентного потока не указывать буфер, то автоматически будет создан динамический буфер, изменяющий размер во время исполнения:
ostream os1; // резидентный поток с динамическим буфером
char Buf[100];
ostream os2(Buf, siseof(Buf)); // резидентный поток со статическим буфером
20. Полнофункционольный ввод/вывод в С++. Перечисляемые типы enum. Ссылочные переменные. Значения аргументов по умолчанию. Функция memset().
Перечисляемые типы enum.
В языке С++ определяемые пользователем перечисляемые типы отличаются от своих аналогов, имеющихся в С. В частности, типы С enum совместимы с типом int. Это означает их взаимозаменяемость, и при этом компилятор не выдаст никаких предупреждений. В С++, однако, эти два типа несовместимы.
Второе различие между перечисляемыми типами С и С++ заключается в том, что при описании перечисляемых переменных в С++ используется более компактная синтаксическая конструкция. В следующем примере показаны отличие типа enum в этих двух языках:
typedef enum boolean {FALSE, TRUE};
void main(void)
{ //enum boolean bflag=0; в С это допустимо, в С++ нет
boolean bcontinue, bflag=FALSE;
bcontinue=(boolean)1;
bflag=bcontinue;}
в начале этого примера определяется перечисляемый тип boolean, который является стандартным в некоторых других языках высокого уровня. В соответствие с очередностью описаний — FALSE, затем TRUE — компилятор присваивает значение 0 константе FALSE и значение 1 — константе TRUE. Это согласуется с логическим смыслом констант в программе.
Закомментированный оператор в функции main() представляет собой допустимый оператор С. Напомним, что при описании перечисляемых переменных в С, например bflag, необходимо использовать ключевое слово enum вместе с полем тега перечисляемого типа — в данном случае это boolean. Поскольку типы С enum совместимы с типами int, также допускается инициализация переменной целым значением. Компилятор С++ не пропустит этот оператор. Эквивалентный ему допустимый оператор С++ показан во второй строке функции main()
Два других оператора в программе показывают, как использовать перечисляемые типы. Обратите внимание на то, что в С++ для преобразования 1 в совместимый тип boolean необходимо явное приведение типа (boolean).
Ссылочные переменные.
Ссылочные переменные — это особенность С++. Если сравнивать ссылки с более сложными конструкциями с указателями, то при их использовании упрощается синтаксис и улучшается читаемость программ. При помощи указателей-параметров программа может передавать данные в функцию, используя вызов по адресу или по ссылке, при этом функция имеет возможность изменять переданные данные. При вызове по значению — напротив — функции посылается копия содержимого переменной. Любые изменения переменной в этом случае будут локальными и не получат отражения в вызывающей процедуре.
В следующей программе структура stStudent передается в функцию; при этом используются три возможных способа вызова: по значению, по ссылке с применением указателя и по ссылке с помощью простейшего ссылочного типа С++. Если подпрограмме передается весь массив, то по умолчанию параметр-массив вызывается по ссылке. Однако отдельные структуры в массиве по умолчанию передаются по значению. Следующий фрагмент кода показывает одновременно прототип каждой функции и соответствующий вызывающий оператор:
void vByValueCall (stStudent);
vByValueCall(astLargeClass[0]);
void vByVariableCall (stStudent *pstAStudent);
vByVariableCall (&astLargeClass[0]);
void vByReferenceCall (stStudent &rstAStudent);
vByReferenceCall(astLargeClass[0]);
Значения аргументов по умолчанию.
В С++ можно записать прототип функции, используя значения аргументов по умолчанию. Это означает следующее: если в вызывающем операторе пропущены некоторые поля, то функция получает заранее определенные значения по умолчанию. Расположение определений параметров по умолчанию в прототипе функции не произвольно: эти определения должны описываться последними в списке формальных параметров.
void fdefault_argument(char ccode = 'Q', int ivalue = 0, float fvalue = 0);
void main(void)
{ fdefault_argument('A', 2, (float)12.34);
fdefault_argument();}
void fdefault_argument(char ccode, int ivalue, float fvalue)
{ if(ccode == 'Q')
cout << "\n\nUsing default values only."; // используются значения только
cout << "\nivalue= " << ivalue; // по умолчанию
cout << "\nfvalue= " << fvalue << endl;}
В данной программе все три формальных параметра имеют значения по умолчанию. Функция fdefault_argument() проверяет значение переменной ccode и включает или выключает соответствующее сообщение. Результат работы программы достаточно прост:
ivalue = 2 fvalue = 12.34 Using default values only. ivalue = 0 fvalue = 0
Функция memset().
Эту функцию можно использовать для присвоения символьных значений ячейкам динамически выделенной памяти — одному или нескольким байтам. Прототип функции memset() выглядит следующим образом:
void *memset(void *dest, int cchar, size_t count);
После вызова memset() переменная dest указывает на count байтов памяти, которые проинициализированы символьным значением cchar. В следующем примере показана разница между статическим и динамическим объявлением структуры:
// функция memset(). Динамическое выделение памяти
struct keybits
{unsigned char rshift, lshift, ctrl, alt, scroll, numlock, caplock, insert;};
void *memset(void *dest, int cchar, size_t count);
void main(void)
{ keybits stkgarbage, *pstkinitialized; pstkinitialized=new keybits;
memset(pstkinitialized, 0, sizeof(keybits));}
Благодаря функции memset(), динамически созданная структура, на которую указывает переменная pstkinitialized, содержит все нули, в то время как статически созданная структура stkgarbage заполнена произвольными значениями. При вызове функции memset() используется операция sizeof() вместо "зашитого" в оператор фиксированного числа. При этом процедура может автоматически выбирать размер любого передаваемого объекта. В С++ при описании структурных переменных, как в случае с переменными stkgarbage и pstkinitialized, не обязательно использовать ключевое слово struct перед полем тега структуры (keybits).
21. Полнофункционольный ввод/вывод в С++. Форматирование потока. Опции ввода/вывода в С/С++. Список классов iostream.
Существуют два способа форматирования ввода/вывода:
Первый способ предусматривает использование функций для установки определенных флагов форматирования:
skipws Пропускает пробельные символы на входе left Осуществляется ввод с левым выравниванием right Осуществляется ввод с правым выравниванием (по умолчанию)
internal Добавляет заполняющие символы после любого знака или указателя системы счисления до начала числа dec Численные значения выводятся в десятичной форме (по умолчанию) oct Численные значения выводятся в восьмеричной форме hex Численные значения выводятся в шестнадцатиричной форме showbase Отображает числовые константы в формате, который может читать компилятор C++
showpoint Приводит к выводу десятичной запятой и нулей справа для всех чисел с плавающей запятой вне зависимости showpos Приводит к тому, что перед положительным числом будет выводится знак "+"
Функции, которые устанавливают и сбрасывают эти флаги.
setf (), используемая для установки флагов
Для отключения установленных флагов нужно использовать функцию unsetf().
Кроме флага форматирования также можно установить ширину поля потока, символ для заполнения и число цифр после десятичной запятой. Для этого используются следующие функции: int width(int len); устанавливает ширину поля и возвращает текущую ширину
char fill(char ch); устанавливает текущий символ заполнения и возвращает предыдущий символ заполнения
int precision(int num); устанавливает текущий символ заполнения и возвращает предыдущий символ заполнения
второго способа форматирования ввода/вывода - это использование манипуляторов.
Манипуляторы являются специальными функциями, которые позволяют изменять флаги потока. Существуют манипуляторы с параметрами и без
манипуляторы без параметров: ends - помещает в выходной поток нулевой символ;
endl помещает в выходной поток символ конца строки и вызывает метод flush;
flush выгружает буфер потока;
dec, hex, oct устанавливают основания 10, 16 и 8 соответственно;
ws заставляет игнорировать ведущие пробелы при вводе.
Манипуляторы с параметрами setbase (int b) задает основание системы счисления;
resetiosflags (long f) сбрасывает флаги, указанные в параметре;
setiosflags (long f) устанавливает флаги, указанные в параметре;
setfill (int ch) задает заполняющий символ;
setprecision (int n) задает точность вещественных чисел;
setw (int n) задает ширину поля.
Пример форматированного вывода
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
void main(void)
{ long double number, factorial; number = 1.0; factorial = 1.0;
cout.precision(0); // нет знаков после запятой
cout.setf(ios::fixed); // фиксированный формат
for(int i=0; i< 25; i++)
{ factorial *= number; number = number + 1.0;
cout.width(30); // ширина 30 символов
cout << factorial << endl; } }
Опции ввода\вывода в С++
в языке С++ отсутствуют какие-либо встроенные процедуры ввода/ввода. Вместо них все компиляторы С++ поставляются с объектно-ориентированными классами iostream. Эти стандартные объекты классов ввода/вывода синтаксически согласованы, поскольку разрабатывались авторами языка С++. Если нужно написать некоторое приложение С++, переносимое на другие компиляторы С++, то можно использовать классы iostream. В компиляторе Visual С/С++ имеются следующие средства (5 вариантов) для осуществления ввода/вывода в С/С++:
Библиотека С небуферизированного ввода/вывода — Компилятор С обеспечивает небуферизированный ввод/вывод при помощи функций _read() и _write().
Буферизированный ввод/вывод ANSI С — В С имеются также буферизированные функции fread() и fwrite(). Они описаны в библиотеке stdio.h и выполняют собственную буферизацию перед непосредственным обращением к базовым процедурам ввода/вывода.
Библиотека С ввода/вывода на консоль и в порты —_getch(), _ungetch() и _kbhit(), обеспечивающие прямой доступ к аппаратному обеспечению.
Библиотека Microsoft классов iostream —предоставляет программам на С++ возможности объектно-ориентированного ввода/вывода. Ее можно использовать вместо таких функций, как scanf(), printf(), fscanf() и fprintf().cin, cout, cerr и clog, не совместимы с графическим интерфейсом пользователя Windows.
Библиотека Microsoft Foundation Class — Класс Microsoft CFile, находящийся в библиотеке МFС, обеспечивает приложения С++ и, в особенности, Windows - приложения средствами объектного дискового ввода/вывода.
Дата добавления: 2015-12-08; просмотров: 256 | Нарушение авторских прав