Задачи редактирования файла

Более сложными являются задачи редактирования файлов на программном уровне. К типовым операциям над файлами можно отнести:

1. Исключение из файла фрагмента текста.

2. Вставка в файл фрагмента текста.

3. Замена фрагмента текста файла на другой фрагмент.

4. Упорядочивание элементов файла по определенному ключу.

Операцию замены можно выполнить с помощью первых двух операций: исключить один фрагмент текста и вставить другой. Но поскольку эта операция широко распространена, она часто рассматривается как отдельная операция.

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

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

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

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

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

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

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

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

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <ctype.h>

#include <io.h>

#define SIZE 40

void main() {

char *buffer,str[SIZE],*pt,*qt,c;

long n;

int i,k,len;

FILE *f;

f = fopen("copy.txt","r+");

//Режим "r" без '+' создает защиту от записи

printf("\n Введите позицию вставки и символ\n");

scanf("%d",&k);

c = getchar();

n = filelength (fileno(f));

len = (int)n + 1;

buffer = (char*)malloc(len);

 

fread(buffer, len,1,f);

fseek(f,0L,SEEK_SET);

/*После команды fread текущая позиция в файле

изменилась, поэтому возврат ее в исходное положение */

//Установить указатель на текущий символ на конец буфера

pt = buffer;

while(*pt++);

qt = pt + 1; //Второй указатель на 1 позицию вправо

for (i = 0; i < len - k + 1; i++)

//Копирование до точки вставки

*qt-- = *pt--;

buffer[k - 1] = c;

//Вставка символа, поскольку место свободно

fwrite(buffer, len,1,f);

fseek(f,0L,SEEK_SET);

//После команды fwrite позиция в файле изменилась

fscanf(f,"%s",str);

printf("\n Cтрока после вставки равна %s",str);

}

 

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

#include <stdio.h>

#include <io.h>

#include <stdlib.h>

#include <conio.h>

#include <ctype.h>

#define SIZE 2000

void main () {

FILE *f1, *f2;

char str[SIZE],c;

int i,n;

f1 = fopen("copy1.txt","w");

f2 = fopen("copy.txt","r");

printf("\nВведите позицию и фрагмент для вставки \n");

scanf("%d%s",&n,str);

if (n > 0 && n <= (int)filelength (fileno(f2)) ) {

//Обработка

i = 1;

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

while(i < n && feof(f2) == 0) {

c = getc(f2);

putc(c,f1);

i++;

}

fputs(str,f1); // Переписать вставляемый фрагмент

//Переписать исходный файл в конечный до конца

while(feof(f2) == 0) {

c = getc(f2);

putc(c,f1);

}

} //Конец оператора if

else printf("\nОшибка ввода параметра смещения (%d)",n);

}

 

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

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

2. Прочесть из входного файла текст до места вставки.

3. Записать прочитанный фрагмент во вспомогательный файл.

4. Записать во вспомогательный файл вставляемый фрагмент.

5. Прочесть из входного файла остаточный фрагмент и записать его во вспомогательный файл.

6. Закрыть оба файла.

 

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

#include <stdio.h>

#define BSIZE 200

void main(){

char argv[20]="task_22.txt";

char buf[BSIZE];

int ch;

FILE *in, *tmp;

in=fopen(argv,"rb");

if(in==NULL)

printf("Не открывается файл %s\n", argv);

else {

tmp = tmpfile();

buf[0]='\t';

while(fgets(buf+1,BSIZE-1,in) != NULL)

fputs(buf,tmp);

fclose(in);

in = fopen(argv,"wb");

fseek(tmp,0l,SEEK_SET);

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

fputc(ch,in);

fclose(in);

fclose(tmp);

}

}

Задания

1.Наберите код программы из Примеров 1, 2. Выполните компиляцию и запуск программ.

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

3.Дан входной файл, каждая строка которого содержит одно целое число. Удалите все числа между первым максимальным и последним минимальным. Дополнительный массив не использовать.

Домашние задания

1.Наберите код программы из Примеров 3, 4. Выполните компиляцию и запуск программ.

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

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

 









Дата добавления: 2015-02-16; просмотров: 1060;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.017 сек.