Работа с файлами в C

Язык C

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

Как работать с файлами

Для открытия потока передачи байтов следует писать следующую конструкцию:

FILE * переменная fopen(имя файла, режим открытия);

Переменная имеет тип структуры FILE . В нее сохраняется результат работы функции fopen, который открывает поток. Первый параметр указывает имя файла и путь к нему, с которым будет происходить манипуляция, второй параметр указывает режим открытия — для записи, чтения, записи и чтения.

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

Пример открытия и закрытия потока:

int main(void)
{
FILE * f = fopen(«D:\text.txt», «w»); \\ Доступ к файлу, который находится по адресу D:\text.txt c параметром «W», который указывает на запись.
fclose(f); \\ Удаление потока
return 0;
}

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

Пример проверки на ошибку:

int main(void)
{
FILE * f; \\ Объявление переменной типа FILE
if((f= fopen(«D:\text25.txt», «r»))==NULL) \\ Проверка на наличие ошибки при открытии потока.
{
perror(«Error:»); Если есть ошибка, то будет выведен ее текст, в нашем случае это «Error No such file or directory».
exit(0); \\Принудительный выход из программы.
}

fclose(f); \\ Если файл открыт, то функция тут же его закроет.
return 0;
}

Для вывода ошибки в консоль, применяется функция perror(string), которая в качестве параметра принимает текст ошибки. В нашем примере не имеет смысла продолжать выполнение программы, поэтому ее принудительно останавливают с помощью функции exit(0).

Текст ошибки из параметра функции perror сопровождается и сообщением компилятора в виде No such file or directory, которое говорит о отсутствия такого файла в указанной директории. Однако некоторые параметры функции fopen позволяют создать несуществующий файл. Если файл с конкретным именем не находится, то он будет создан заново.

Опции-параметры для открытия файлов

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

  • wb — запись бинарного файла.
  • rb – чтение бинарного файла.
  • ab – продожение записи.
  • w+b – создается бинарный файл для чтения и записи.
  • r+b – чтение или запись бинарного файла.
  • a+b – если файл отсутствует, то создается, если присутствует и заполнен, то продолжение записи.

Те же параметры применяются и для текстовых файлов, только без символа «b». Режимы задаются чтобы расширить возможности манипуляций с файлом и ограничить их до чтения или только записи. Также режимы задают формат файла — бинарный или текстовый. Неправильно установленный режим может привести либо к ошибке, либо к некорректной интерпретации файла.

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

Для записи символов или строки в текстовый файл используется функция fputs(). Синтаксис данной функции следующий: int fputs( const char ch, FILE f); Здесь первый параметр ch принимает записываемую строку или символ. Второй параметр указывает на открытый файловый поток. Если при записи произошла ошибка, то функция возвращает значение ошибки EOF.

Пример записи теста в файл:

int main(void)
{
char * mes = «Hello, my name is Vova»; \\Сохраняем строку для записи в файл
char * fName = «D://text5.txt»; \\Сохраняем путь к файлу
char c[256];
FILE * f;

if((f= fopen(fName, «w»))==NULL) \\Если возникла ошибка при открытии файла, то вывести сообщение «Error» и выйти из программы
{
perror(«Error»);
return 1;
}

fputs(mes, f); \\ Запись в файл строки в переменной mes

fclose(f);
return 0;

}

Так как в данном примере был использован режим открытия «W», то нам открывается пустой файл для записи. Если после выполнения данного кода открыть файл text5.txt, то в его содержании будет строка «Hello, my name is Vova».

Позиционирование указателя при записи файла

Режим «r» или «w» устанавливает каретку записи в начало файла. Режим «a» устанавливает каретку в конец имеющихся данных. Таким образом первый вариант перезаписывает файл, второй дописывает. При записи или чтении каретка передвигается на позицию, равную числу прочитанных или записанных байтов, или символов.

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

У данной функции следующий синтаксис: fseek(файл, количество байтов для смещения, начальная позиции);

Пояснение к функции:

  1. Параметр «файл» является переменной типа FILE, указывающая на директорию его расположения.
  2. Параметр «количество байтов для смещения» обладает типом long и в числовом формате указывает на сколько символов нужно переместить каретку.
  3. Параметр «начальная позиция» имеет числовой тип и указывает на каком по порядку от начала байте нужно установить каретку файла.
  4. В третий параметр можно вписать одну из встроенных в структуру FILE констант: SEEK_SET — устанавливает позицию на начало файла; SEEK_CUR — сохраняет текущую позицию в файле, если она была смещена; SEEK_END — устанавливает каретку на конечную позицию.

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

int main(void){
int i; \\ Переменная для сохранения символов в цикле
char * str = «Hello»; \\ Первая строка записываемая в файл
char * final_str; \\ Строка для дописывания в файл
File * f = fopen(«text.txt», w);
fputs(str, f); \\ Записываем первую строку в файл

fseek(f, 6, SEEK_SET); \\ Устанавливаем каретку на 6-ю позицию
fputs(«World!», f); \\ С шестой позиции записываем в файл строку «World!»
fseek(f, 0, SEEK_SET); \\ Устанавливаем позицию каретки в начало

while ((i = getc(f))!=EOF) \\ Получаем каждый символ файла и сохраняем его в переменную «final_str»
{
*final_str +=(char *)i;
}

printf(«Содержание файла:», final_str); \\ Выводим содержимое файла на консоль
fclose(f);
}

Основные функции для работы с файлами в языке Си

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

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

  • File fopen(f, option) — принимает в качестве аргумента путь к фалу и режим открытия потока, создает поток для записи или чтения текстовых или бинарных данных. Если нет возможности открыть файл, а режим не предусматривает его создания, то возвращает NULL.
  • File freopen(dir, option, f) — аналогичная функция предыдущей, однако первый параметр указывает только путь к фалу, а последний имя файла.
  • fclose(str) — закрывает поток для освобождения памяти от потока, в качестве параметра принимает путь к фалу или объект FILE.

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

  • fgets(f) — читает символ из файла и возвращает его числовой формат int, если результат успешный, то возвращает следующий файл. Если возникает ошибка то возвращает EOF.
  • getc(f) — аналогичная предыдущей функции, но возвращает только один символ в числовом формате.

Запись в файл

  • fwrite(chararr, sizeb, sizec, f) — функция записывает массив символов chararr в файл. Второй параметр указывает размер каждого байта, третий параметр указывает количество байтов, четвертый является объектом File или строковой директорией к нему. Если запись осуществилась успешно, то функция вернет sizec в формате int.
  • fputc(number, f) — первый параметр конвертирует числовой код символа в сам символ и записывает его в поток f. Если запись прошла успешно, то возвращается записанный символ первого параметра, в случае неудачи возвращается EOF.

Считывание русских символов из файла

setlocale(LC_ALL, «Russian») — вызов данной функции позволяет настроить поток на работу с кириллицей.

Первый параметр является языковой константой, которая активирует выбор языка символов, второй параметр устанавливает язык для чтения и записи. Прежде, чем использовать данную функцию, необходимо в начале программы подключить директиву #include <iostream>.

Отличие работы с потоками в Си от других языков

Как видно, язык Си не использует обращение к объектам для оперирования с файлами. Для открытия потока здесь даже не применяется конструкция new IOstream(). Ведь Cи является процедурным языком и в нем не используется парадигма ООП. Тем не менее, если открывать поток без сохранения в переменную, то дальнейшее применение функций должно сопровождаться записью в их параметры директории к файлу, какая была указана при открытии.

Ранее мы создавали переменную “f” для сохранения потока. Без нее всегда придется писать строку на подобие “C\:files\index.txt”. Данный подход достаточно неудобный и требует постоянной записи строки. При этом, все равно придется закрывать поток. Проще сохранить его в переменную – это дает гарантию тог, что работа всегда осуществляется с данным потоком.

Заключение

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

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

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

Оцените статью
Образовательный портал WELCOME4U.RU
Добавить комментарий

Adblock
detector