Основные методы обработки текстовых файлов.

Используется только последовательный метод доступа, который обеспечивается функциями fprintf() и fscanf()

Файловые функции ввода/вывода fprintf() и fscanf() работают аналогично printf() и scanf(), но имеют дополнительный аргумент, являющийся указателем на файловый поток.

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

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

void main(){

FILE *f;

int dig;

if (f = fopen(“inp_f”, ”r”) == NULL) //открыть файл для чтения

{ printf(“Невозможно открыть файл!\n”);

exit(0);

}

fscanf(f, “%d”, &dig); // считать значение dig из файла

fclose(f); // закрыть файл

f = fopen(“out_f”, “w”);// открыть др. файл для записи

fprintf(f, “Прочитано число %d”, dig);

fclose(f); // закрыть файл

}

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

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

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <string.h>

void main(int argc, char *argv[]){

FILE *f_in, *f_out;

int ch;

char *name; // имя входного файла

int count = 0; // счетчик элементов

if (argc<2) // в командной строке нет имени

{ printf(“Введите имя входного файла”);

gets(name);

}

else name = argv[1]; // взять имя из командной строки

if ((f_in = fopen(name, ”r”))!= NULL) //открыть файл для чтения

{ strcat(name, “.out”); // добавляет расширение .out к

// имени файла

f_out = fopen(name, ”w”); // открывает файл для записи

while((ch = fgetc(f_in)!=EOF)

if(count++%3 == 0)

fputc(ch, f_out); // выводит каждый 3-й символ

fclose(f_in);

fclose(f_out);

}

else printf(“Невозможно открыть файл!\n”);

}

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

Рассмотрим построчное чтение информации из входного файла и вывод ее на экран как на стандартное устройство вывода.

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <string.h>

void main(int argc, char *argv[]){

FILE *f_in;

char buffer[256]; // максимальная длина строки - 255 символов

char *name; // имя входного файла

if (argc<2) // в командной строке нет имени

{ printf(“Введите имя входного файла”);

gets(name);

}

else name = argv[1]; // взять имя из командной строки

if ((f_in = fopen(name, ”r”))!= NULL) //открыть файл для чтения

{ while(fgets(buffer, 255, f_in))!= NULL)

{fputs(buffer, stdout);

fputs(‘\n’, stdout);

}

fclose(f_in);

else printf(“Невозможно открыть файл!\n”);

}

В цикле while присутствуют две файловые функции работы со строками: fgets() – для чтения строки символов и fputs() – для записи содержимого буфера в файл

Кроме того, вывод текстового файла буферизован. Это значит, что в тот момент, когда работает оператор записи в файл, фактическая запись может не происходить, поскольку реально сначала идет заполнение данными текстового буфера, а потом его содержимое записывается на диск. Запись буфера происходит как только он окажется полностью заполненным или при выполнении специальных команд принудительной записи на диск. Процесс записи недозаполненнгого буфера на диск называется флэшированием и обычно выполняется с помощью функции fflush(f_out).При необходимости завершить работу сразу со всеми открытыми файлами пользуются функцией flushall().

Закрытие файла посредством функции fclose(f_out) также включает процесс флэширования, т.е. перенос информации из буфера на диск.

Пример. Допустим, что в файле хранятся сведения о мониторах. В каждой строке указан тип, оптовая и розничная цены и примечание. Для простоты данные в каждой строке записаны единообразно (совокупность строк – таблица): первые 20 символов занимает тип монитора, далее по 5 символов целые числа, представляющие цены, затем примечание длиной не более 40 символов.

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

#include <iostream.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int main()

FILE *fi, *fo;

if ((fi = fopen(“d:\\c\\file.txt”, “r”)) == 0){

cout << “Ошибка открытия входного файла”; return 1;}

if ((fo = fopen(“d:\\c\\binfile.out”, “w+b”)) == 0){

cout << “Ошибка открытия выходного файла”; return 1;}

const int dl = 80;

char s [dl];

struct{

char type [20];

int opt, rozn;

char comm[40];} mon;

int kol = 0; // количество записей в файле

while (fgets (s, dl, fi)){

// преобразование строки в структуру

strcnpy(mon.type, s, 19);

mon.type[19]=’\0’;

mon.opt = atoi(&s[20]);

mon.rozn = atoi(&s[25]);

strcnpy(mon.comm, &s[30], 40);

fwrite(&mon, sizeof mon, 1, fo);

kol++;

}

fclose(fi);

int i; cin >>i; // номер записи

if (i >= kol){ cout << “Запись не существует”; return 1;}

// установка указателя текущей позиции файла на запись i:

fseek (fo, (sizeof mon)*i, SEEK_SET);

fread (&mon, sizeof mon,1, fo);

cout << “type” << mon.type <<”opt” << mon.opt

<< “rozn” << mon.rozn << endl;

flose (fo);

return 0;

}

Наши рекомендации