Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпоры печатать.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
379.36 Кб
Скачать

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 - приложения средствами объектного дискового ввода/вывода.

Список классов iostream. Классы потокового ввода.Классы потокового вывода

Все объекты ввода/вывода, описанные в библиотеке iostream, используют оди и тот же базовый класс ios (за исключением классов буферизованных потоков). Эти производные классы делятся на 4 категории.

  • Классы потокового ввода

Istream

Используется как универсальное средство ввода или как родительский класс для других производных классов потокового ввода

Ifstream

Используется для ввода из файлов

istream_withassign

Используется для ввода из потока cin

Istrstream

Используется для ввода строк

  • Классы потокового вывода

Ostream

Используется как универсальное средство потокового вывода или как родительский класс для других производных классов потокового вывода

Ofstream

Используется для вывода в файл

ofstream_withassign

Используется для вывода в потоки cout, cerr и clog

Ostrstream

Используется для вывода строк

  • Классы потокового ввода/вывода

  • Классы буферизированных потоков

22. Полнофункционольный ввод/вывод в С++. Классы потокового ввода. Классы потокового вывода. Классы буферизированных потоков. Класс строковых потоков.

Все объекты ввода/вывода, описанные в библиотеке iostream, используют оди и тот же базовый класс ios (за исключением классов буферизованных потоков). Эти производные классы делятся на 4 категории.

  • Классы потокового ввода

Istream

Используется как универсальное средство ввода или как родительский класс для других производных классов потокового ввода

Ifstream

Используется для ввода из файлов

istream_withassign

Используется для ввода из потока cin

Istrstream

Используется для ввода строк

  • Классы потокового вывода

Ostream

Используется как универсальное средство потокового вывода или как родительский класс для других производных классов потокового вывода

Ofstream

Используется для вывода в файл

ofstream_withassign

Используется для вывода в потоки cout, cerr и clog

Ostrstream

Используется для вывода строк

  • Классы потокового ввода/вывода

  • Классы буферизированных потоков

Потоковый ввод текста

#include "stdafx.h"

#include <iostream>

#include <fstream>

#include <math.h>

using namespace std;

#define iCOLUMNS 80

void main(void)

{ char cOneLine[iCOLUMNS];

ifstream ifInputS("ifstrm.cpp", ios::in);

while(ifInputS)

{ifInputS.getline(cOneLine, iCOLUMNS); cout << '\n' << cOneLine;}

ifInputS.close();}

для создания объекта ifstream и связывания его с дескриптором открытого файла ifInputS используется конструктор класса ifstream. Этот оператор содержит имя файла,а также текстовый режим.. При наличии опции ios::nocreate выполняется проверка существования файла. Целое значение дескриптора файла ifInputS для логических проверок. Метод getline(), унаследованный от класса ifstream, позволяет читать полные строки текста, заканчивающиеся null-символом. имеет три параметра: указатель char *, количество вводимых символов — включая null-символ — и '\n', имена массивов char являются указателями на символы, переменная cOneLine удолетворяет требованиям первого параметра метода. Количество вводимых символов соответствуют размеру массива — iCOLUMNS. Опция разделителя отсутствует. Однако, если входные строки разделяются специальным символом — например, '*' -, то оператор getline() можно записать так:

ifInputS.getline(cOneLine, iCOLUMNS,'*') ;

Затем в приведенной программе печатаются строки, и файл закрывается явно при помощи метода ifInputS.close().

Список классов iostream. Классы буферизированных потоков.Класс строковых потоков

Все объекты ввода/вывода, описанные в библиотеке iostream, используют оди и тот же базовый класс ios (за исключением классов буферизованных потоков). Эти производные классы делятся на 4 категории.

  • Классы потокового ввода

  • Классы потокового вывода

  • Классы потокового ввода/вывода

  • Классы буферизированных потоков

Streambuf

Используется как родительский класс для производных объектов

Filebuf

Класс буферизированных потоков для дисковых файлов

strstreambuf

Класс буферизированнных потоков для строк

Stdiobuf

Класс буферизированных потоков для стандартного файлового

Класс streambuf является основой для потокового ввода/вывода в С++. В нем описаны все основные операции, выполняемые с символьными буферами. Также используется для порождения класса файловых буферов (класс filebuf) и классов istream и ostream, содержащих указатели на объекты streambuf.

Класс строковых потоков

Класс streambuf можно использовать для расширения возможностей класса iostream. Все буферизированные объекты класса streambuf используют фиксированный буфер памяти, называемый областью резервирования. Эту область можно разделить на get-область для ввода и put-область для вывода.

Для объектов streambuf имеются два конструктора, имеющие следующий синтаксис:

streambuf::streambuf();

streambuf::streambuf (char * рг, int nLength) ;

Первый конструктор используется косвенно всеми порожденными от streambuf классами. Он устанавливает в null все внутренние указатели объекта типа streambuf. Второй конструктор создает объект типа streambuf, связывающийся с существующим символьным массивом.

применение класса streambuf

#include "stdafx.h"

#include <iostream>

#include <fstream>

#include <math.h>

#include <strstream>

using namespace std;

#define iNYBUFFSIZE 1024

void main(void)

{

char c;

strstreambuf stbMyStreamBuf(iNYBUFFSIZE);

stbMyStreamBuf.sputc('A'); // отдельный символ выдается в буфер

c = stbMyStreamBuf.sgetc();

cout << c << endl;

}

23. Полнофункционольный ввод/вывод в С++. Двоичные файлы. Часто применяемые функции. Объединение программ на С и С++. Использование спецификатора extern "С".

Двоичные файлы

Двоичные файлы или потоки содержат последовательность байтов, полностью соответствующих их представлению на внешнем устройстве. В двоичном файле число прочитанных или записанных байтов совпадает с числом байтов, располагающихся в файле на внешнем устройстве.

Если в программе необходимо считывать исполняемый файл, то это нужно делать в двоичном режиме. Двоичные файлы также используются при считывании и записи чисто информационных файлов, например баз данных.

Объединение программ на С и С++. Использование спецификатора extern "С"

ключевое слово extern указывает на внешнюю связь переменной или функции. В С/С++ можно использовать extern вместе со строкой. Эта строка указывает на то, что для описываемых идентификаторов используются соглашения о компоновке другого языка. По умолчанию для программ С++ задается строка "С++".

По умолчанию в С++ функции можно перегружать. При этом компилятор С++ каждой функции присваивает новое имя. Эту операцию можно отменить, если указать перед описанием функции extern "С". Это необходимо для того, чтобы из программы, написанной на С++, были доступны функции и данные С. Синтаксис записи extern "С" выглядит следующим образом:

extern "С" тип_ функции имя_ функции(тип_параметра (тип_параметров) параметр (параметры));

Следующий оператор показывает, как запись extern "С" используется вместе с прототипом отдельной функции:

extern "С" int fprintf(FILE *stream, char *format, ...);

Для модификации группы прототипов функций нужны фигурные скобки {}:

extern "С" {

….

}

В следующем фрагменте кода модифицируются прототипы функций getc() и рutc():

extern "С" {

int getc(FILE *stream);

int putc(int с, FILE *stream);

}

Ниже приведена программа, показывающая, как использовать запись extern "С":

#include "stdafx.h"

#include <iostream>

#include <fstream>

#include <math.h>

#include <strstream>

using namespace std;

#define iMAX 9

extern "C" int imycompare(const void *pi1, const void *pi2);

void main(void)

{

int iarray[iMAX]={1, 9, 2, 8, 3, 7, 4, 6, 5};

for(int i=0; i < iMAX; i++)

cout << iarray[i] << " ";

cout << endl;

qsort(iarray,iMAX, sizeof(int), imycompare);

for(i = 0; i < iMAX; i++)

cout << iarray[i] << " ";

cout << endl;

}

extern "C" int imycompare(const void *pi1, const void *pi2)

{

return(*(int *)pi1 - *(int *)pi2);

}

24. Полнофункционольный ввод/вывод в С++. Создание пользовательских манипуляторов. Манипуляторы без параметров. Манипуляторы с одним параметром. Манипуляторы с несколькими параметрами.

Манипуляторы используются вместе с операциями вставки «и выделения » аналогично выходным данным или входным переменным.

Порядок создания пользовательского манипулятора с параметрами, например для вывода:

  1. Определить класс (MyManip) с полями: параметры манипулятора, указатель на функцию типа ostream &(*f) (ostream &, <параметры манипулятора>);

  2. Определить конструктор этого класса (MyManip) с инициализацией полей.

  3. Определить, в этом классе дружественную функцию - operator <<. Эта функция в качестве правого аргумента принимает объект класса MyManip, левого аргумента (операнда) поток ostream и возвращает поток ostream как результат выполнения функции *f. Например,

typedef ostream &(*PTF) (ostream &, int, int, char);

class MyManip

{

public:

// конструктор

MyManip(PTF F, int W, int N, char FILL)

: f(F),

w(W),

n(N),

fill(FILL)

{}

protected:

int w; int n; char fill; PTF f;

friend ostream &operator <<(ostream &, MyManip); };

ostream &operator <<(ostream &out, MyManip my)

{ return my.f(out, my.w, my.n, my.fill);}

  1. Определить функцию типа *f(fmanip), принимающую поток и параметры манипулятора и возвращающую поток. Эта функция собственно и выполняет форматирование. Например,

ostream &fmanip(ostream &s, int w, int n, char fill)

{ s.width(w); s.flags(ios::fixed); s.precision(n); s.fill(fill); return s; }

  1. Определить собственно манипулятор (wp) как функцию, принимающую параметры манипулятора и возвращающую объект MyManip, поле f которого содержит указатель на функцию fmanip. Например,

MyManip wp(int w, int n, char fill)

{ return MyManip(fmanip, w, n, fill); }

Для создания пользовательских манипуляторов с параметрами можно использовать макросы, которые содержатся в файле <iomanip.h>:

OMANIP(int) IMANIP(int) IOMANIP(int)

Манипуляторы без параметров

Манипуляторы без параметров:

dec - при вводе и выводе устанавливает флаг десятичной системы счисления;

hex - при вводе и выводе устанавливает флаг шестнадцатеричной системы счисления;

oct - при вводе и выводе устанавливает флаг восьмеричной системы счисления;

ws - действует только при вводе и предусматривает извлечение из входного потока пробельных символов (пробел, знаки табуляции '\t' и '\v', символ перевода строки '\n', символ возврата каретки '\r', символ перевода страницы '\f');

endl - действует только при выводе, обеспечивает включение в выходной поток символа новой строки и сбрасывает буфер (выгружает содержимое) этого потока;

ends - действует только при выводе и обеспечивает включение в поток нулевого признака конца строки;

Без специальных манипуляторов операторы вывода будут выглядеть так:

cout << '\а' << "\n\n\t\tImportant data: " << fcritical_mass << endl; // Важные данные

using namespace std;

ostream& beep(ostream& os)

{return os << '\a' << "\n\n\t\t\tImportant data: ";}

void main(void)

{ double fcritical_mass = 12459876.12; cout << beep << fcritical_mass << endl;}

Создание пользовательских манипуляторов. Манипуляторы с одним параметром

// манипультор с одним параметром

#include <iostream.h>

#include <iomanip.h>

#include <string.h>

#define iSCREEN_WIDTH 80

ostream& fc(ostream& os, int istring_width)

{

os << '\n';

for(int I = 0; I < ((iSCREEN_WIDTH - istring_width)/2); i++)

os << ' ';

return (os);

}

OMANIP(int) center(int istring_width)

{

return OMANIP(int) (fc, istring_width);

}

void main(void)

{

char *psz="This is auto-centered text!"; // автоцентрирующийся текст

cout << center(strlen(psz)) << psz << endl;

}

Пользовательский параметризованный манипулятор center принимает одно значение, strlen(psz), представляющее собой длину строки. В файле iomanip.h описывается макрос OMANIP(int), расширяемый в класс __OMANIP_int. Описание этого класса включает конструктор и перегруженную операцию вставки в поток ostream. Когда функция center() включается в поток, она вызывает конструктор, который создает и возвращает объект __OMANIP_int. Затем конструктор объектов вызывает функцию fc().