Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


ХРАНЕНИЕ ДАННЫХ НА ВНЕШНИХ НОСИТЕЛЯХ




Цель работы :

1. Получение практических навыков записи структурированной информации в файлы в стиле С;

2. Получение практических навыков записи структурированной информации в файлы в стиле С++.

 

Задание:

  1. Используя ввод-вывод в стиле С создать файл и записать в него структурированные данные.
  2. Вывести созданный файл на экран.
  3. Удалить из файла данные в соответствии с вариантом.
  4. Добавить в файл данные в соответствии с вариантом.
  5. Вывести измененный файл на экран.
  6. Используя ввод-вывод в стиле С++ создать файл и записать в него структурированные данные.
  7. Вывести созданный файл на экран.
  8. Удалить из файла данные в соответствии с вариантом.
  9. Добавить в файл данные в соответствии с вариантом.
  10. Вывести измененный файл на экран.

 

Длительность:4 часа.

Теоретические основы: Особенностью С является отсутствие в этом языке структурированных файлов. Все файлы рассматриваются как не структурированная последовательность байтов. При таком подходе понятие файла распространяется и на различные устройства.

В С существуют средства ввода-вывода. Все операции ввода-вывода реализуются с помощью функций, которые находятся в библиотеке С. Библиотека С поддерживает три уровня ввода-вывода:

- потоковый ввод-вывод;

- ввод-вывод нижнего уровня;

- ввод-вывод для консоли и портов (зависит от ОС).

Поток – это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику.

Чтение данных из потока называется извлечением, вывод в поток – помещением, или включением.

Поток определяется как последовательность байтов и не зави­сит от конкретного устройства, с которым производится обмен (оперативная па­мять, файл на диске, клавиатура или принтер). Обмен с потоком для увеличения скорости передачи данных производится, как правило, через специальную об­ласть оперативной памяти — буфер. Буфер накапливает байты, и фактическая передача данных выполняется после заполнения буфера. При вводе это дает возможность исправить ошибки, если данные из буфера еще не отправлены в программу.

При работе с потоком можно:

- открывать и закрывать потоки (связывать указатели на поток с конкретными файлами);

- вводить и выводить строку, символ, форматированные данные, порцию данных произвольной длины;

- анализировать ошибки ввода-вывода и достижения конца файла;

- управлять буферизацией потока и размером буфера;

- получать и устанавливать указатель текущей позиции в файле.

Функции библиотеки ввода-вывода находятся в заголовочном файле <stdio.h>.

Прежде чем начать работать с потоком, его надо инициировать, т. е. открыть. При этом поток связывается со структурой предопределенного типа FILE, определение которой находится в библиотечном файле <stdio.h>. В структуре находится указатель на буфер, указатель на текущую позицию файла и т. п. При открытии потока, возвращается указатель на поток, т. е. на объект типа FILE.

#include <stdio.h>;

. . . . . . . .

FILE *fp;

. . . . . . . . . . ..

fp= fopen( ”t.txt”, ”r”);

где fopen(<имя_файла>,<режим_открытия>) - функция для инициализации файла.

Существуют следующие режимы для открытия файла:

Режим Описание режима открытия файла
r Файл открывается для чтения, если файл не существует , то выдается ошибка при исполнении программы.
w Файл открывается для записи, если файл не существует, то он будет создан, если файл уже существует, то вся информация из него стирается.
a Файл открывается для добавления, если фай не существует, то он будет создан, если существует, то информация из него не стирается, можно выполнять запись в конец файла
r+ Файл открывается для чтения и записи, изменить размер файла нельзя, если файл не существует , то выдается ошибка при исполнении программы.
w+ Файл открывается для чтения и записи, если файл не существует, то он будет создан, если файл уже существует, то вся информация из него стирается.
a+ Файл открывается для чтения и записи, если фай не существует, то он будет создан, если существует, то информация из него не стирается, можно выполнять запись в конец файла

Поток можно открыть в текстовом (t) или двоичном (b) режиме. По умолчанию используется текстовый режим. В явном виде режим указывается следующим образом:

”r+b”или ”rb” - двоичный (бинарный) режим;

”r+t” или ”rt” – текстовый режим.

В файле stdio.h определена константа EOF, которая сообщает об окончании файла (отрицательное целое число).

При открытии потока могут возникать следующие ошибки:

- файл, связанный с потоком не найден (при чтении из файла);

- диск заполнен (при записи);

- диск защищен от записи (при записи) и т. п.

В этих случаях указатель на поток приобретет значение NULL (0). Указатель на поток, отличный от аварийного не равен 0.

Для вывода об ошибке при открытии потока используется стандартная библиотечная функция из файла <stdio.h>

void perror (const char*s);

 

if ((fp=fopen(”t.txt”, ”w”)==NULL)

{

// выводит строку символов с сообщением об ошибке

perror(”\nошибка при открытии файла”);

exit(0);

}

После работы с файлом, его надо закрыть

fclose(<указатель_на_поток>);

Когда программа начинает выполняться, автоматически открываются несколько потоков, из которых основными являются:

- стандартный поток ввода (stdin);

- стандартный поток вывода (stdout);

- стандартный поток вывода об ошибках (stderr).

По умолчанию stdin ставится в соответствие клавиатура, а потокам stdout и stderr - монитор. Для ввода-вывода с помощью стандартных потоков используются функции:

- getchar()/putchar() – ввод-вывод отдельного символа;

- gets()/puts() – ввод-вывод строки;

- scanf()/printf() – форматированный ввод/вывод.

Аналогично работе со стандартными потоками выполняется ввод-вывод в потоки, связанные с файлами.

Для символьного ввода-вывода используются функции:

int fgetc(FILE*fp), где fp – указатель на поток, из которого выполняется считывание. Функция возвращает очередной символ в форме int из потока fp. Если символ не может быть прочитан, то возвращается значение EOF.

int fputc(int c, FILE*fp), где fp – указатель на поток, в который выполняется запись, c – переменная типа int, в которой содержится записываемый в поток символ. Функция возвращает записанный в поток fp символ в форме int . Если символ не может быть записан, то возвращается значение EOF.

Для построчного ввода-вывода используются следующие функции:

char* fgets(char* s,int n,FILE* f), где char*s – адрес, по которому размещаются считанные байты, int n – количество считанных байтов, FILE* f – указатель на файл, из которого производится считывание.

Прием байтов заканчивается после передачи n-1 байтов или при получении управляющего символа ‘\n’. Управляющий символ тоже передается в принимающую строку. Строка в любом случае заканчивается ‘\0’. При успешном завершении работы функция возвращает указатель на прочитанную строку, при неуспешном – 0.

int puts(char* s, FILE* f), где char*s – адрес, из которого берутся записываемые в файл байты, FILE* f – указатель на файл, в который производится запись.

Символ конца строки (‘\0’) в файл не записывается. Функция возвращает EOF, если при записи в файл произошла ошибка, при успешной записи возвращает неотрицательное число.

Для блокового ввода-вывода используются функции:

int fread(void*ptr,int size, int n, FILE*f), где void*ptr – указатель на область памяти, в которой размещаются считанные из файла данные, int size – размер одного считываемого элемента, int n – количество считываемых элементов, FILE*f – указатель на файл, из которого производится считывание.

В случае успешного считывания функция возвращает количество считанных элементов, иначе – EOF.

int fwrite(void*ptr,int size, int n, FILE*f), где void*ptr – указатель на область памяти, в которой размещаются считанные из файла данные, int size – размер одного записываемого элемента, int n – количество записываемых элементов, FILE*f – указатель на файл, в который производится запись.

В случае успешной записи функция возвращает количество записанных элементов, иначе – EOF.

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

int fprintf(FILE *f, const char*fmt,. . .) , где FILE*f – указатель на файл, в который производится запись, const char*fmt – форматная строка, . . . – список переменных, которые записываются в файл.

Функция возвращает число записанных символов.

int fscanf(FILE *f, const char*fmt, par1,par2, . . .) , где FILE*f – указатель на файл, из которого производится чтение, const char*fmt – форматная строка, par1,par2,. . . – список переменных, в которые заносится информация из файла.

Функция возвращает число переменных, которым присвоено значение.

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

int fseek(FILE *f, long off, int org), где FILE *f - – указатель на файл, long off – позиция смещения, int org – начало отсчета.

Смещение задается выражение или переменной и может быть отрицательным, т. е. возможно перемещение как в прямом, так и в обратном направлениях. Начало отсчета задается одной из определенных в файле <stdio.h> констант:

SEEK_SET ==0 – начало файла;

SEEK_CUR==1 – текущая позиция;

SEEK_END ==2 – конец файла.

Функция возвращает 0, если перемещение в потоке выполнено успешно, иначе возвращает ненулевое значение.

Потоковый ввод-вывод в стиле С++

С++ предоставляет возможность ввода/вывода как на низком уровне – неформатированный ввод-вывод, так и на высоком – форматированный ввод-вывод. При неформатированном вводе/выводе передача информации осуществляется блоками байтов данных без какого-либо преобразования. При форматированном - байты группируются таким образом, чтобы их можно было воспринимать как типизированные данные (целые числа, строки символов, числа с плавающей запятой и т. п.)

По направлению обмена потоки можно разделить на входные (данные вводятся в память), выходные (данные выводятся из памяти), двунаправленные (допускающие как извлечение, так и включение).

По виду устройств, с которыми работает поток, потоки можно разделить на стандартные, файловые и строковые:

- стандартные потоки предназначены для передачи данных от клавиатуры и на экран дисплея,

- файловые потоки — для обмена информацией с файлами на внеш­них носителях данных (например, на магнитном диске),

- строковые потоки — для работы с массивами символов в оперативной памяти.

Для работы со стандартными потоками библиотека C++ содержит библиотеку <iostream.h>. При этом в программе автоматически становятся доступными объекты:

- cin - объект, соответствует стандартному потоку ввода,

- cout - объект, соответствует стандартному потоку вывода.

Оба эти потока являются буферизированными.

Форматированный ввод/вывод реализуется через две операции:

- << - вывод в поток;

- >> - чтение из потока.

Использование файлов в программе предполагает следующие операции:

- создание потока;

- открытие потока и связывание его с файлом;

- обмен (ввод/вывод);

- уничтожение потока;

- закрытие файла.

Для работы со файловыми потоками библиотека C++ содержит библиотеки:

- <ifstream.h> - для работы с входными потоками,

- <ofstream.h> - для работы с выходными потоками

- <fstream.h> - для работы с двунаправленными потоками.

В библиотечных файлах потоки описаны как классы, т. е. представляют собой пользовательские типы данных (аналогично структурам данных). В описание класса, кроме данных, добавляются описания функций, обрабатывающих эти данные (соответственно компонентные данные и компонентные функции (методы)). Обращаться к компонентным функциям можно также как и к компонентным данным с помощью . или ->.

Для создания файлового потока используются специальные методы–конструкторы, которые создают поток соответствующего класса, от­крывают файл с указанным именем и связывают файл с потоком:

- ifstream(const char *name, int mode = ios::in);//входной поток

- ofstream(const char *name, int mode = ios::out | ios::trunc);//выходной поток

- fstreamCconst char *name, int mode = ios::in | ios::out);//двунаправленный поток

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

ios::in открыть файл для чтения;
ios::out открыть файл для записи;
ios::ate установить указатель на конец файла, читать нельзя, можно только записывать данные в конец файла;
ios::app открыть файл для добавления;
ios::trunc если файл существует, то создать новый;
ios::binary открыть в двоичном режиме;
ios::nocreate если файл не существует, выдать ошибку, новый файл не открывать
ios::noreplace если файл существует, выдать ошибку, существующий файл не открывать;

Открыть файл в программе можно с использованием либо конструкторов, либо метода open, имеющего такие же параметры, как и в соответствующем конструкторе.

fstream f; //создает файловый поток f

//открывается файл, который связывается с потоком

f.open(“..\\f.dat”,ios::in);

// создает и открывает для чтения файловый поток f

fstream f (”..\\f.dat”,ios::in);

После того как файловый поток открыт, работать с ним можно также как и со стандартными потоками cin и cout. При чтении данных из входного файла надо контролировать, был ли достигнут конец файла после очередной операции вывода. Это можно делать с помощью метода eof().

Если в процессе работы возникнет ошибочная ситуация, то потоковый объект принимает значение равное 0.

Когда программа покидает область видимости потокового объекта, то он уничтожается, при этом перестает существовать связь между потоковым объектом и физическим файлом, а сам файл закрывается. Если файл требуется закрыть раньше, то используется метод close().

//создание файла из элементов типа person

struct person

{

char name[20];

int age;

};

person *mas;//динамический массив

fstream f("f.dat",ios::out);//двунаправленный файловый поток

int n;

cout<<"N?";

cin>>n;

mas=new person[n];//создаем динамический массив

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

{

cout<<"?";

//ввод одного элемента типа person из стандартного потока cin

cin>>mas[i].name;

cin>>mas[i].age;

}

//запись элементов массива в файловый поток

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

{

 

f<<mas[i].name;f<<"\n";

f<<mas[i].age;f<<"\n";

 

}

f.close();//закрытие потока

 

//чтение элементов из файла

person p;

f.open("f.dat",ios::in);//открываем поток для чтения

do

{

/*читаем элементы типа person из файлового потока f в переменную p*/

f>>p.name;

f>>p.age;

// если достигнут конец файла, выходим из цикла

if (f.eof())break;

//вывод на экран

cout<<p.name<<" "<<p.age<<"\n";

 

}while(!f.eof());

f.close();//закрытие потока

 

Задания по вариантам к лабораторной работе №11:

№ варианта Структура данных Удаление Добавление
Структура "Абитуриент": - фамилия, имя, отчество; - год рождения; - оценки вступительных экзаменов (3); - средний балл аттестата.   Удалить элемент с указанным номером.   Добавить K элементов в начало файла
Структура "Сотрудник": - фамилия, имя, отчество; - должность - год рождения; - заработная плата.   Удалить элемент с указанной фамилией Добавить K элементов в конец файла
Структура "Государство": - название; - столица; - численность населения; - занимаемая площадь.   Удалить все элементы, у которых численность меньше заданной.   Добавить элемент с номером К
Структура "Человек": - фамилия, имя, отчество; - домашний адрес; - номер телефона; - возраст.   Удалить все элементы с заданным возрастом.   Добавить N элементов с номером К
Структура "Человек": - фамилия, имя, отчество; - год рождения; - рост; - вес.   Удалить все элементы с указанным ростом и весом.   Добавить K элементов в начало файла
Структура "Школьник": - фамилия, имя, отчество; - класс; - номер телефона; - оценки по предметам (математика, физика, русский язык, литература).   Удалить все элементы, у которых есть 2 хотя бы по одному предмету.   Добавить K элементов в конец файла
Структура "Студент": - фамилия, имя, отчество; - домашний адрес; - группа; - рейтинг.   Удалить все элементы, у которых рейтинг меньше заданного.   Добавить элемент с номером К
Структура "Покупатель": - фамилия, имя, отчество; - домашний адрес; - номер телефона; - номер кредитной карточки Удалить К элементов из начала файла.   Добавить N элементов с номером К
Структура "Пациент": - фамилия, имя, отчество; - домашний адрес; - номер медицинской карты; - номер страхового полиса.   Удалить элемент с заданным номером медицинской карты.   Добавить K элементов в начало файла
Структура "Информация": - носитель; - объем; - название; - автор.   Удалить первый элемент с заданным объемом информации.   Добавить K элементов в конец файла
Структура "DVD-диск": - название фильма; - режиссер; - продолжительность; - цена.   Удалить все элементы с ценой выше заданной.   Добавить элемент с номером К
Структура "DVD- диск": - название; - режиссер; - продолжительность; - цена.   Удалить первый элемент с заданной продолжительностью.   Добавить N элементов с номером К
Структура "Спортивная команда": - название; - город; - количество игроков; - количество набранных очков.   Удалить все элементы с количеством очков меньше заданного.   Добавить K элементов в начало файла
Структура "Стадион": - название; - адрес; - вместимость; - виды спорта.   Удалить элемент с заданным названием.   Добавить K элементов в конец файла
Структура "Автомобиль": - марка; - год выпуска; - цена; - цвет.   Удалить все элементы, у которых год выпуска меньше заданного.   Добавить элемент с номером К
Структура "Владелец автомобиля": - фамилия, имя, отчество; - номер автомобиля; - телефон; - номер техпаспорта.   Удалить элемент с заданным номером.   Добавить N элементов с номером К
Структура "Фильм": - название; - режиссер; - год выпуска; - стоимость.   Удалить все элементы, у которых стоимость превышает заданную.   Добавить K элементов в начало файла
Структура "Книга": - название; - автор; - год издания; - количество страниц.   Удалить К элементов из начала файла.   Добавить K элементов в конец файла
Структура "Фильм": - название; - режиссер; - страна; - приносимая прибыль.   Удалить К элементов , начиная с номера N из файла.   Добавить элемент с номером К
Структура "Государство": - название; - государственный язык; - денежная единица; - курс валюты относительно $.   Удалить элемент с указанным названием.   Добавить N элементов с номером К
Структура "Автомобиль": - марка; - серийный номер; - регистрационный номер; - год выпуска.   Удалить все элементы с указанной маркой Добавить K элементов в начало файла
Структура "Владелец автомобиля": - фамилия, имя, отчество; - номер автомобиля; - номер техпаспорта; - отделение регистрации ГАИ.   Удалить элемент с заданным номером.   Добавить K элементов в конец файла
1. Структура "Стадион": - название; - год постройки; - количество площадок; - виды спорта.   Удалить все элементы, у которых год постройки меньше заданного.   Добавить элемент с номером К
Структура "Студент": - фамилия, имя, отчество; - номер телефона; - группа; - оценки по 3 основным предметам.   Удалить все элементы из группы с указанным номером, у которых среднее арифметическое оценок меньше заданного.   Добавить N элементов с номером К
Структура "Студент": - фамилия, имя, отчество; - дата рождения; - домашний адрес; - рейтинг.   Удалить все элементы с указанным рейтингом Добавить N элементов с номером К

 

Требования к отчёту по лабораторной работе:

1. оформить отчет по соответствующим требованиям (титульный лист)

2. сформулировать цель работы

3. задание;

4. схема алгоритм программы;

5. текст программы;

6. выводы по результатам выполнения лабораторной работы;

7. список используемой литературы (обязательно из электронной библиотеки).

 


Поделиться:

Дата добавления: 2015-02-09; просмотров: 198; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.007 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты