close

Вход

Забыли?

вход по аккаунту

?

Ответы КПиЯП(23-27)

код для вставкиСкачать
 23.Понятие файла. Связь файла с потоком ввода-вывода. Получение информации о статусе ввода-вывода. Пример использования.
Файл - это именованная область памяти на одном из дисков, в которой может храниться текст программы, какое-либо из ее промежуточных представлений, исполняемая программа или данные для ее работы.
Каждый файл имеет имя. Имя файла складывается из двух частей: собственно имени и расширения имени (типа), разделяемых точкой.
Для организации работы с файлами используются классы потоков ifstream (ввод), ofstream (вывод) и fstream (ввод и вывод). Файл открывается путем стыковки его с соответствующим потоком.
ofstream(const char* Name, int nMode= ios::out, int nPot= filebuf::openprot);
ifstream(const char* Name, int nMode= ios::in, int nPot= filebuf::openprot);
Первый аргумент определяет имя файла (единственный обязательный параметр). Второй аргумент задает режим для открытия файла и представляет битовое ИЛИ ( | ) величин:
* ios::app при записи данные добавляются в конец файла, даже если текущая позиция была перед этим изменена функцией ostream::seekp;
* ios::ate указатель перемещается в конец файла. Данные записываются в текущую позицию (произвольное место) файла;
* ios::in поток создается для ввода, если файл уже существует, то он сохраняется;
* ios::out поток создается для вывода (по умолчанию для всех ofstream объектов), если файл уже существует, то он уничтожается;
* ios::trunc если файл уже существует, его содержимое уничтожается (длина равна нулю). Этот режим действует по умолчанию, если ios::out установлен, аios::ate, ios::app или ios:in не установлены;
* ios::nocreate если файл не существует, функциональные сбои;
* ios::noreplace если файл уже существует, функциональные сбои;
* ios::binary ввод-вывод будет выполняться в двоичном виде (по умолчанию текстовой режим).
Третий аргумент - данное класса filebuf, используется для установки атрибутов доступа к открываемому файлу. * filebuf::sh_compat совместно используют режим;
* filebuf::sh_none режим Exclusive: никакое совместное использование;
* filebuf::sh_read совместно использующее чтение;
* filebuf::sh_write совместно использующее запись.
Есть несколько функций, позволяющих определить статус потока:
int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);
int fileno(FILE *stream);
Их использование:
feof() Возвращает не ноль, если достигнут конец потока. Конец потока считается достигнут, если выставлен соответствующий флаг в структуре FILE. Этот флаг выставляется при попытке прочитать данные, а данные потока(файла) закончились.
ferror() возвращает не ноль, если была ошибка при работе с потоком.
clearerr() опускает флаг ошибки и флаг достижения конца файла.
fileno() возвращает номер файлового дескриптора, связанного с потоком.
Файловые дескрипторы для стандартных потоков stdin, stdout, stderr равны 0, 1, 2 соответственно. Файловый дескриптор - это номер строки в таблице файловых дескрипторов, каждая строка которой содержит адрес структуры, описывающей I/O в какой-либо файл.
#include "iostream.h"
#include "fstream.h"
#include "string.h"
class string
{ char *st;
int size;
public : string(char *ST,int SIZE) : size(SIZE)
{ st=new char[size];
strcpy(st,ST);
}
~string() {delete [] st;}
string(const string &s) { st=new char[s.size]
strcpy(st,s.st);}
friend ostream &operator<<(ostream &,const string);
friend istream &operator>>(istream &,string &);};
ostream &operator<<(ostream &out,const string obj)
{ out << obj.st << endl;
return out;
}
istream &operator>>(istream &in,string &obj)
{ in >> obj.st;
return in;
}
main()
{ string s("asgg",10),ss("aaa",10);
int state;
ofstream out("file");
if (!out)
{ cout<<"ошибка открытия файла"<<endl;
return 1; // или exit(1)
}
out<<"123"<<endl;
out<<s<<ss<<endl; // запись в файл
ifstream in("file");
while(in >> ss) // чтение из файла
{cout<<ss<<endl;}
in.close();
out.close();
return 0;
}
24. Доступ к данным файла в текстовом режиме: открытие и закрытие файла, операции чтения и записи. Пример использования.
Файлы позволяют пользователю считывать большие объемы данных непосредственно с диска, не вводя их с клавиатуры. Существуют два основных типа файлов: текстовые и двоичные.
Текстовыми называются файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом "конца строки". Конец самого файла обозначается символом "конца файла". При записи информации в текстовый файл, просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.
Для работы с файлами используются специальные типы данных, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения, а ofstream в режиме записи. Для работы с файлами в режиме как записи, так и чтения служит поток fstream.
В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.
Для того чтобы записывать данные в текстовый файл, необходимо:
1. описать переменную типа ofstream.
2. открыть файл с помощью функции open.
3. вывести информацию в файл.
4. обязательно закрыть файл.
Для считывания данных из текстового файла, необходимо:
1. описать переменную типа ifstream.
2. открыть файл с помощью функции open.
3. считать информацию из файла, при считывании каждой порции данных необходимо проверять, достигнут ли конец файла.
4. закрыть файл.
Открыть в режиме записи можно одним из следующих способов:
//первый способ ofstream F;
F.open("D:\\sites\<strong>\</strong>accounts<strong>.</strong>txt", ios::out);
//второй способ, режим ios::out является режимом по умолчанию
//для потока ofstream ofstream F;
F.open("D:\\game\\noobs.txt");
//третий способ объединяет описание переменной и типа поток
//и открытие файла в одном операторе
ofstream F("D:\\game\\noobs.txt", ios::out);
Здесь F - переменная, описанная как ofstream, file - полное имя файла на диске, mode - режим работы с открываемым файлом.(см. вопрос 23).
Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока.
После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверить корректность операции открытия файла.
Для того чтобы прочитать информацию из текстового файла, необходимо описать переменную типа ifstream. После этого нужно открыть файл для чтения с помощью оператора open.
ifstream F;
F.open("D:\\sites\\accounts.txt", ios::in);
После открытия файла в режиме чтения из него можно считывать информацию указав имя потока, из которого будет происходить чтение данных.
F>>a; (то же справедливо и для записи)
Перед каждым считыванием проверяем, достигнут ли конец файла.
while(!F.eof()) {F>>a;}
Закрытие потока, а тем самым и файла: F.close();
25. Доступ к данным файла в бинарном режиме: открытие и закрытие файла, операции чтения и записи. Пример использования.
В двоичных файлах информация считывается и записывается в виде блоков определенного размера, в которых могут храниться данные любого вида и структуры.
Для того чтобы записать/прочитать данные в/из двоичный файл, необходимо:
1. описать переменную типа FILE *
2. открыть файл с помощью функции fopen
3. считать необходимую информацию из файла с помощью функции fwrite/fread, при этом следить за тем достигнут ли конец файла.
4. закрыть файл с помощью функции fclose
Для открытия файла предназначена функция fopen.
FILE *fopen(const *filename, const char *mode)
Здесь filename - строка, в которой хранится полное имя открываемого файла,mode - строка, определяющая режим работы с файлом; возможны следующие значения:
* "rb" - открываем двоичный файл в режиме чтения;
* "wb" - создаем двоичный файл для записи; если он существует, то его содержимое очищается;
* "ab" - создаем или открываем двоичный файл для дозаписи в конец файла;
* "rb+" - открываем существующий двоичный файл в режиме чтения и записи;
* "wb+" - открываем двоичный файл в режиме чтения и записи, существующий файл очищается;
* "ab+" - двоичный файл открывается или создается для исправления существующий информации и добавления новой в конец файла.
Функция возвращает в файловой переменной f значение NULL в случае неудачного открытия файла. После открытия файла доступен 0-й его байт, указатель файла равен 0, значение которого по мере чтения или записи смещается на считанное (записанное) количество байт. Текущие значение указателя файла - номер байта, начиная с которого будет происходить операция чтения или записи.
int fclose(FILE *filename);
Возвращает 0 при успешном закрытие файла и NULL в противном случае. Чтение из двоичного файла осуществляется с помощью функции fread:
fread(void *ptr, size, n, FILE *filename);
Функция fread считывает из файла filename в массив ptr n элементов размера size. Функция возвращает количество считанных элементов. После чтения из файла его указатель смещается на n*size байт.
Запись в двоичный файл осуществляется с помощью функции fwrite:
fwrite(const void *ptr, size, n, FILE *filename);
Функция fwrite записывает в файл filename из массива ptr n элементов размераsize. Функция возвращает количество записанных элементов. После записи информации в файл указатель смещается на n*size байт.
Для контроля достижения конца файла есть функция feof:
int feof(FILE *filename);
Она возвращает ненулевое значение если достигнут конец файла.
//запись
FILE *f; //описываем файловую переменную
//создаем двоичный файл в режиме записи
f=fopen("D:\\game\\noobs.dat","wb");
//ввод числа n
cin>>n;
fwrite(&n, sizeof(int), 1, f);
//чтение
FILE *f; //описываем файловую переменную
//открываем существующий двоичный файл в режиме чтения
f=fopen("D:\\game\\noobs.dat", "rb");
//считываем из файла одно целое число в переменную n
fread(&n, sizeof(int) , 1, f);
//вывод n на экран
cout<<"n="<<n<<endl;
26. Пространства имен. Вложенные и неименованные пространства имен. Обращение к элементам пространства имен. Необходимость создания и пример использования.
При совпадении имен разных элементов в одной области действия часто возникает конфликт имен. Наиболее часто это возникает при использовании различных пакетов библиотек, содержащих, например, одноименные классы.
Пространства имен используются для разделения глобального пространства имен, что позволяет уменьшить количество конфликтов. Синтаксис пространства имен некоторым образом напоминает синтаксис структур и классов. После ключевого слова namespace следует необязательное имя пространства имен, затем описывается пространство имен, заключенное в фигурные скобки.
По существу, namespace определяет область видимости.
namespace NAME
{ int a;
doudle b;
char *fun(char *,int);
class CLS
{ . . .
public:
. . . }}
Далее, если обращение к элементам пространства имен производится вне контекста, его имя должно быть полностью квалифицировано, используя ::
NAME::b=2;
NAME:: fun(str,NAME:: a);
Контексты пространства имен могут быть вложены.
namespace NAME1
{ int a;
namespace NAME2
{ int a;
int fun1(){return NAME1:: a}; // возвращается значение первого a
int fun2(){return a}; // возвращается значение второго a
}
}
NAME1::NAME2::fun1(); // вызов функции
Существует неименованное пространство имен специального типа, которое позволяет создавать идентификаторы, которые можно использовать только в данном файле. Общий формат его объявления выглядит так.
namespace {
//объявления
}
Неименованные пространства имен, позволяют устанавливать уникальные идентификаторы, которые известны только в области видимости одного файла. Другими словами, члены файла, который содержит неименованное пространство имен, можно использовать напрямую, без уточняющего префикса. Но вне файла эти идентификаторы неизвестны.
Использование идентификатора типа static также позволяет ограничить область видимости глобального пространства имен файлом, в котором он объявлен.
27. Использование встроенного ассемблера. Вызов ассемблерной процедуры из С-функции. Вызов функций, написанных на С из программ на языке ассемблера.
Вызов ассемблерной процедуры из С-функции.
C++ поддерживает два способа передачи параметров в вызываемую функцию: стандартный способ языка С и с использованием модификатора pascal.
Рассмотрим программу на языке С++, использующую первый способ передачи параметров.
extern "C" void asm_f1(int *i1, int *i2, unsigned long l1);
void main(void)
{ int i=5, j=7;
unsigned long l=0x12345678;
asm_f1(&i, &j, l);
}
Строка extern "C" void asm_f1(int *i1, int *i2, unsigned long l1); определяет, что программа asm_f1 описана в другом файле. Особенностью компилятора языка C++ является то, что если не заданы специальные режимы, он добавляет перед своими идентификаторами символ подчеркивания (_). Таким образом идентификатор asm_f1 после компиляции будет выглядеть как _asm_f1. Это необходимо учесть при написании процедуры asm_f1 на языке ассемблера. Спецификатор "С" говорит о том, что используется интерфейс между программами, принятый в языке С.
Далее вызывается функция asm_f1 на языке ассемблера и ей передаются три параметра: i, j и l. Передача параметров из вызывающей в вызываемую программу осуществляется через стек. В соответствии со способом, принятым в С , параметры передаются в стек справа налево, то есть сначала l, потом &j и далее &i. Следом за параметрами в стек помещается адрес возврата, то есть адрес команды в языке C++, которая следует за командой asm_f1(&i, &j, l);. Если для программы на языке С++ заданы малые модели памяти (tiny, small, compact), то таким адресом возврата является значение IP (для следующей после asm_f1 команды). Если для программы на языке C++ заданы большие модели памяти (medium, large, huge), то адресом возврата является значение CS:IP ( для следующей после asm_f1 команды).
Вызов программ на языке С++ из программ на языке ассемблера.
Как и выше, для каждой программы необходимо указать, какие переменные она передает в другой модуль и какие переменные она получает из другого модуля. Для этого необходимо выполнить следующее:
1. Если функция на языке С++ вызывается из программы на языке асемблера, то такая функция в языке ассемблера должна быть описана как EXTRN (должна появиться после дрективы EXTRN).
2. Описание всех глобальных переменных должно быть выполнено в соответствии с правилами, описанными в предыдущем параграфе.
3. Если функция на С++ возвращает значение, то оно будет помещено в регистры в соответствие с соглашениями языка С++.
Документ
Категория
Разное
Просмотров
61
Размер файла
33 Кб
Теги
ответы, кпияп, шпаргалки, шпоры
1/--страниц
Пожаловаться на содержимое документа