Сделай Сам Свою Работу на 5

ПЗ_03 Файловый ввод/вывод





1 Цель занятия изучить основные способы файлового ввода и вывода данных в С и С++.

2 Краткие методические указания.Система ввода/вывода для описания процессов обмена информацией с внешними устройствами использует два понятия: поток данных и файл[Ш-192]. Поток описывает процесс взаимодействия – чтение, запись, строка, символ, а файл является абстрактным объектом, описывающим внешнее устройство. Для описания этого объекта используется специальная область, указатель на которую имеет типFILE. Перед началом работы с этим устройством (файлом) необходимо определить состояние этой области – выполнить своеобразный конструктор объекта файл – открыть файл. Для открытия файла используется специальная функция открытия файла, которая имеет следующий прототип:

FILE *fopen(const char *имя файла, const char *режим) – функция возвращает значение указателя на файл (область описывающую соответствующий объект), если файл удалось открыть и возвращает NULL, если открыть файл не удалось – не удалось выполнить конструктор этого объекта. Строка имя файла определяет имя или путь к открываемому файлу [Ш-192]. Строка режим определяет процесс взаимодействия потока данных с файлом. Определить причину не открытия файла можно выполнив функцию int ferror(FILE *fp), параметр которой fp указывает на открываемый файл.



В зависимости от типа внешнего устройства потоки, открываемые для файла функцией fopen могут иметь разные режимы работы. Эти режимы перечислены в таблице 9.2 [Ш-195]. Например, для устройства печати или экрана необходимо открыть поток для записи, так как на эти устройства данные только записываются. С устройства клавиатура можно только читать данные.

Потоки для файлов могут быть текстовыми или бинарными. Текстовый поток интерпретируется как поток символов, часть из которых могут управлять устройством. Коды текстовых (печатных) и управляющих символов приведены в таблице кодов символов ASCII. Для управления некоторыми устройствами в символьном потоке к коду 0х0А – новая строка, приписывается код 0х0D – возврат каретки. Поэтому передаваемая последовательность может оказаться короче потока поступившего на устройство. Если на устройство передается бинарный поток, то число переданных и принятых кодов совпадает. Ниже приведена программа записывающая в файл DATA.dt 256 первых натуральных чисел в режиме текстового потока.



// Fl_IO.cpp : Defines the entry point for the console application.

//Запись данных в символьный и бинарный файл

#include "stdafx.h"

#include <stdio.h>

#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[]){

FILE *fp;//Описываем указатель для описателя файла fp

if(!(fp=fopen("DATA.dt","w+"))){//Создание текстового файла

printf("File open is Err\n");//Сообщение об ошибке

return 1;//Прекращение работы при ошибке открытия файла

}

for(int i=0;i<256;i++)putc((char)i,fp);//Запись в файл

return 0;

}

Эта программа открывает в текущей директории программы текстовый файл для чтения и записи - DATA.dt и записывает в него 256 первых натуральных чисел. После завершения программы получен файл, показанный на рисунке 1, который содержит больше 256-ти чисел.

 

Рис 1. Текстовый файл для 256 первых натуральных чисел.

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

Для использования файла в программе необходимо проверять результат выполнения функции открытия файла. Если файл открыть не удалось, то функция fopen возвращает значение NULL. После открытия файла и его использования файл должен быть закрыт. Операционная система позволяет открывать ограниченное число файлов. Поэтому использованные файлы следует сразу закрывать. Закрытие файла производиться функцией int fclose(FILE *fp), которая возвращает NULL, если файл fp, открытый раннее, закрыт успешно.



В приведенной выше программе в файл записываются отдельные байты, представляющие первые 256 натуральных чисел. Для работы с текстовыми файлами в файлы можно записывать и читать из них строки символов [Ш-200]. Наиболее распространенные функции работы с файлами перечислены в таблице9.1 [Ш-194].

Для реализации файлового ввода/вывода в языке С++ необходимо к программе подключать заголовочные файлы классов:

  • ifstream – для использования потоков ввода;
  • ofstream– для использованияпотоков вывода;
  • fstream– для использования потоков ввода и вывода.

В каждом из классов определены методы для работы с потоками и файлами, которые описаны в [Ш-438]. Для открытия файла (определения свойств потока и начального состояния файла) используется метод open. Прототип этого метода использует следующие параметры:

ifstream::open(const *filename, ios::mode); - где

filename – строка, определяющая путь к открываемому файлу;

mode – флаг режима открытия файла из родительского класса ios.

Флаги режимов в этом классе имеют следующие обозначения:

ios::app – данные из выходного потока записываются в конец файла:

ios::ate –при открытии указатель в конце файла, но его можно передвигать;

ios::binary –файл открывается в бинарном режиме;

ios::in – файл открывается для чтения (ввода из файла);

ios::out – файл открывается для записи (вывода в файл);

ios::trunk – при открытии старое содержимое файла уничтожается (очищается).

Например, для открытия на запись бинарного файла test из текущей директории необходимо выполнить следующий фрагмент программы:

ofstream outs;//Определяем поток вывода и

outs::open(“test”,ios::out | ios::binary);//открываем бинарный файл для этого потока.

Значения флагов режима открытия могут определяться по умолчанию [Ш-438]

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

ofstream outs;//Определяем поток вывода и

outs::open(“test”);//открываем бинарный файл для этого потока.

Здесь используется значение флага ios::out, заданное для потока ofstream по умолчанию. Классы ifstream, ofstreamи fstreamсодержат конструкторы, которые открывают файлы. Поэтому текстовый файл test можно открыть на запись следующим образом

ofstream outs(“test”);

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

исполнительной программы.

//Печатает свой исполнительный файл

 

#include "stdafx.h"

#include <iostream>

#include <fstream>

using namespace std;

 

int _tmain(int argc, _TCHAR* argv[]){

setlocale(LC_ALL, "rus");//Установка кодовой таблицы для кириллицы

ifstream flpr(argv[0]);//Связываем поток ввода с файлом

if(!flpr){cout << "Не открывается указанный файл\n"; return 1;}

//Читаем символы из файла и печатаем

while(!flpr.eof())cout<< hex << flpr.get();

cout << endl;//Вывод символа перевод строки.

flpr.close();//Закрываем файл

return 0;

}

В эту программу включены интерфейсные файлы для использования файловой системы и ввода вывода. Оператор using определяет стандартное пространство имен. Перед исполнением программы необходимо в свойствах проекта указать путь к исходному коду программы. Обратите внимание, что пробелы являются разделителями строк в командной строке. Поэтому пути, в которых встречаются пробелы, надо заключать в кавычки. После успешного открытия файла выполняется цикл считывания (flpr.get()) и печати символов прочитанных из файла. Цикл завершается после окончания потока, который определяется функцией flpr.eof().

Для чтения и записи порций данных размер которых превышает один байт можно использовать функции [Ш-444] :

istream &read(char* bff, streamsize ln); - чтение из входного потока ln байт в буфер bff.

ostream &write(const char *bff, streamsize ln); - запись в выходной поток ln байт из bff.

Для определения ln размера буфера для размещения считанных данных в оперативной памяти необходимо воспользоваться функциями обеспечивающими произвольный доступ к элементам потока [Ш-450] seekg (seekр). Эта функция перемещает указатель к заданному элементу файла. Функция [Ш-453] tellg (tellp) позволяет определить позицию указателя. Следующий фрагмент программы позволяет определить длину файла fldata и прочитать его в выделенную для этого память:

streamsize LnData = 0;

flData.seekg(0,ios::end);//Определяем длину файла Data

LnData=flData.tellg();//в потоке ввода

BYTE* Pbff = static_cast<BYTE*>(malloc(LnData));//Выделение места для

ZeroMemory(Pbff,LnData);//очистка выделенного места

flData.seekg(0,ios::beg);//Возвращаем указатель позиции в начало потока

flData.read(Pbff,LnData);//Читаем значение из файла

 

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

}

3 Порядок выполнения задания.

3.1 Изучить раздел Ввод/вывод на консоль [Ш-174]

3.2 Переработать программу «Запись данных..» так, что бы она записывала в файл то, что формируется. Указание - место сохранения надо открыть как бинарный файл. В отчете показать, что записывается ровно 256 кодов.

3.3 Разработать программу средствами языка С++, которая читает файл своего исходного кода и печатает его.

3.4 Изучить раздел «Файловая система» [Ш-438].

3.5 Разработать программу средствами языка С++, которая вводит вашу фамилию, имя и отчество (ФИО), записывает ФИО в файл указанный в командной строке, читает этот файл в символьный массив и печатает содержимое массива на экране. Программа должна реализовать следующий алгоритм:

П1. Вводит ФИО.

П2. Проверить указание используемого файла. Если файл не указан, то сообщить и завершить выполнение, иначе напечатать имя указанного файла.

П3. Открыть указанного файла на запись. Если файл не открыт, то сообщить и завершить выполнение, иначе сообщить об открытии файла.

П4. Запись в файл ФИО

П5. Закрыть файл .

П6 Открыть файл с ФИО на чтение. Если файл не открыт, то сообщить и завершить выполнение, иначе сообщить об открытии.

П7. Определить длину открытого для чтения файла и напечатать ее.

П8. Выделить в оперативной памяти место для размещения ФИО.

П9. Прочитать из открытого файла данные в массив, выделенный для ФИО.

П10. Напечатать прочитанные данные.

П11. Закрыть открытый файл.

П12. Завершить программу.

Разработку любой программы целесообразно начинать с разработки такого словесного алгоритма.

3.6 Результаты выполнения задания задокументировать в отчете.

 

Вопросы по теме занятия.

1 Как описывается процесс открытия файла.

2 Чем отличаются текстовые и бинарные файлы. Почему для обмена числовыми данными следует использовать бинарные файлы.

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

4 Почему открытые программой файлы должны быть закрыты после выполнения программы.

5 Как определить размер памяти, который необходимо выделить для чтения содержимого файла.

6 Как определить завершение файла при его чтении функцией get(s);.

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.