C запись и чтение из файла

Открытие и закрытие файлов

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

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:
FILE *myfile;

С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения ("r"), записи ("w") или добавления ("a") и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:
myfile = fopen ("hello.txt", "r");

При чтении или записи данных в файл обращение к нему осуществляется посредством файлового указателя (в данном случае, myfile).

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

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

После того, как работа с файлом закончена, принято его закрывать, чтобы освободить буфер от данных и по другим причинам. Это особенно важно, если после работы с файлом программа продолжает выполняться. Разрыв связи между внешним файлом и указателем на него из программы выполняется с помощью функции fclose() . В качестве параметра ей передается указатель на файл:
fclose(myfile);

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

Чтение из текстового файла и запись в него

fscanf()

Функция fscanf() аналогична по смыслу функции scanf() , но в отличии от нее осуществляет форматированный ввод из файла, а не стандартного потока ввода. Функция fscanf() принимает параметры: файловый указатель, строку формата, адреса областей памяти для записи данных:
fscanf (myfile, "%s%d", str, &a);

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

Допустим, у нас есть файл содержащий такое описание объектов:

Тогда, чтобы считать эти данные, мы можем написать такую программу:

В данном случае объявляется структура и массив структур. Каждая строка из файла соответствует одному элементу массива; элемент массива представляет собой структуру, содержащую строковое и два числовых поля. За одну итерацию цикл считывает одну строку. Когда встречается конец файла fscanf() возвращает значение EOF и цикл завершается.

fgets()

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

Например:
fgets (str, 50, myfile)

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа ‘
‘, который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ ‘’, добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет ‘’. В таком случае ‘
‘ в считанной строке содержаться не будет.

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

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

Запись в каждую строку файла полей одной структуры:

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки ‘
‘):

Пример посимвольного вывода:

Чтение из двоичного файла и запись в него

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

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка "rb" или "wb".

Тема о работе с двоичными файлами достаточно сложная, для ее изучения требуется отдельный урок. Здесь будут отмечены только особенности функций чтения-записи в файл, который рассматривается как поток байтов.

Функции fread() и fwrite() принимают в качестве параметров:

  1. адрес области памяти, куда данные записываются или откуда считываются,
  2. размер одного данного какого-либо типа,
  3. количество считываемых данных указанного размера,
  4. файловый указатель.

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно "заказать" считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

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

Чтение из файла

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

Стандартная библиотека языка C++ включает множество функций для работы с файлами. Описание функций можно найти в сети или в учебниках по C++. Здесь же я опишу одну, которая позволит произвести чтение строки из файла.

Для начала определимся с файлом, с которого будем считывать информацию. Я создал файл с именем «strings.txt» и записал в него информацию, которую буду считывать в массив и выводить на экран.

Содержание файла strings.txt

Три строки, содержащиеся в файле, я запишу массив и выведу на экран.

Пингвин читает содержимое файла

Переходим к написанию программы на C++.

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

Объявим две целочисленные константы len и strings, они будут хранить максимальную длину наших строк и количество строк. Объявим символьную константу ch, которая будет хранить разделяющий символ. Первые две константы будут использоваться для объявления массива. Мой файл содержит 3 строки

При помощи значений двух первых констант объявим двумерный массив символов.

Создадим объект класса ostream, в конструктор поместим адрес файла, флаги открытия.

Флаг ios::in позволяет открыть файл для считывания, ios::binary открывает его в двоичном режиме.

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

В данный момент программа имеет такой вид

Теперь остается описать алгоритм считывания строк из файла и занесения их в массив с последующим выводом. Для этого понадобится цикл от нуля до strings с инкрементом переменной r. Во время каждого прохода цикла используем перегруженную функцию getline() объекта fs с тремя аргументами.

fs.getline(Массив_символов, Макс_длина_строки, Разделитель_строк)

Функция считывает символы из файла, пока не считает количество равное Макс_длина_строки, либо не встретит на своём пути символ равный Разделитель_строк, а после записывает считанные символы в Массив_символов. В качестве разделителя в моём текстовом файле используется перенос строки.

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

Работа с файлами. Побайтовое чтение/запись. Чтение текстовых данных

Любой ввод и вывод информации в .Net Framework включает в себя использование потоков.

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

В пространстве имен System.IO хранятся классы, предназначенные для считывания и записи данных в файлы. Классы:

File – содержит статические методы для манипуляции файлами (создание, копирование, удаление); Directory – содержит статические методы для манипуляции директориями;

Path – статических класс, «путь»; FileInfo – не обладает статическими методами, соответствует физическому фалу, во многом дублирует функциональность File;

FileStream – представляет поток, указывающий на файл или местоположение в сети. Представляет файл для считывания/записи, оперирует байтами и массивом байтов, в то время как Stream оперирует символьными данными.

Класс FileStream поддерживает внутренний указатель файла, ссылающийся на то место в файле, в котором будет производиться очередная операция чтения/записи. Метод Seek() позволяет осуществить поиск конкретной позиции в файле (байтовой).

При чтении и записи в файл, происходит изменение позиции указателя (при считывании на 1б)

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

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

StreamReader – осуществляет чтение символьных данных из потока и их преобразование.

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

Path – путь к файлу/директории, подлежащей контрою.

NotifyFilter – сочетание значений перечисляемого типа NotifyFilters, которое позволяет определить за наступлением каких именно событий для данных файлов следует наблюдать. < Attributes, CreationTime, DirectoryName, FileName, LastAccess, LastWrite, Security, Size >. Допускается использование различных сочетаний этих значений посредством оператора | или &.

Filter – фильтр, определяющий какие именно файлы подлежат контролю, например, *.txt

EnableRaisingEvents – после задания всех свойст необходимо присвоить значение true, что будет означать начало наблюдения .

Асинхронный доступ к файлам

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

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

Создается экземпляр класса AsyncReader, а заме продолжается выполнение – вывод порядковых чисел на консоль; теперь этому методу не приходиться отслеживать процедуру считывания, и он может выполнять какие-либо другие действия, совершенно от этой процедуры не зависящие. Метод HandleRead вызывается системой, когда завершается процедура считывания файла. Это позволяет приложению продолжать обработку какой-либо иной информации, пока выполняется относительно медленная процедура считывания файла.

Оцените статью
Много толка
Добавить комментарий