Посимвольная работа с текстовым файлом

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

FILE *cf; char ch;

//Функция для создания текстового файла

void MyCreate()

{ if ((cf=fopen("d:\\ANA\\cpp\\2005_06\\ FileChar\\textf1.dat","w"))==NULL)

{ printf("Error\n"); return; }

else printf("File is opened for creating\n");

cout<<" 0 – exit\n";

do { ch=getchar(); // Чтение одного символа с экрана

fputc(ch,cf); }

//Один символ из оперативной памяти(ch) перемеcтили в файл(cf).

while (ch!='0');

fclose(cf); }

/* Объявление, открытие и закрытие файла объяснялось в §1. Функция

int fputc(int ch, FILE *stream)

записывает один символ в указанный поток в позицию, соответствующую текущему значению указателя положения в файле и после этого даёт ему приращение. В качестве первого фактического параметра естественно использовать символьную переменную. Если используется целое число, то старший байт отбрасывается. Функция возвращает значение записанного символа. Заметим, что в приведенном выше алгоритме символ ‘0’ будет записан в файл. Позже можно использовать его для проверки, весь ли файл прочитан. Если по какой-либо причине этот символ записывать в файл не надо, можно цикл изменить так:

do { ch=getchar(); if ch == '0') break;

fputc(ch,cf); } while (1); */

// Функция для добавления символов в конец созданного текстового файла

void MyAppend()

{if(cf=fopen("d:\\ANA\\cpp\\2005_06\\FileChar\\textf1.dat”,"a")) ==NULL)

{ printf("Error\n"); return;

}

else printf("File is opened for appending\n");

cout<<"# – exit\n"<<endl;

do { ch=getchar();

fputc(ch,cf);

}

while (ch!='#'); fclose(cf);

}

/* Как видим, эта функция почти ничем не отличается от предыдущей функции создания файла. Только при открытии файла вместо режима “ w ” указан “ a ”, так как мы открываем файл для добавления в его конец. */

//Функция для просмотра созданного файла, то есть для вывода на экран.

void MyRead()

{ puts("look file");

if ((cf= fopen("d:\\ANA\\cpp\\2005_06\\ FileChar\\textf1.dat ","r"))==NULL)

{ printf("Error during opening a file\n"); return;

}

ch=fgetc(cf); /* читаем первый символ вне цикла из файла (cf) и размещаем его в оперативную память в ячейку ch */

while (ch!=EOF) // или while(!feof(cf)) (+)

{ putchar(ch); // вывод прочитанного символа ch на экран

ch=fgetc(cf); } // читаем очередной символ в цикле

fclose(cf); }

int main()

{ int flag=1;

while (1) { cout << "\n1 -- CREATE"<<endl<<

"2 -- READ"<<endl<<

"3 -- APPEND"<<endl<<

"0 -- EXIT"<<endl;

cin>>flag; switch (flag)

{ case 1: MyCreate(); break;

case 2: MyRead(); break;

case 3: MyAppend(); break;

case 0: return 0;

}

}

}

Функция int fgetc (FILE *stream) возвращает следующий за текущей позицией символ из входного потока и даёт приращение указателю положения в файле. При достижении конца файла и в случае ошибки чтения функция возвращает целое число EOF. Это значение, как видим, можно использовать для организации цикла.

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

Во втором варианте для проверки, достигнут ли конец как текстового, так и двоичного файла, связанного с указанным потоком, можно использовать функцию int feof(cf ). Она возвращает ненулевое значение, если указатель положения в файле находится в его конце, то есть если достигнут конец файла. В имени функции первые буквы словосочетания E nd O f F ile (конец файла). В противном случае возвращается нуль. Особенно эта функция полезна при работе с двоичным файлом. В этом случае надо явно вызывать эту функцию, а не просто сравнивать возвращаемую переменную с целочисленным значением, равным EOF, как это разрешено для текстового файла.

Заметим, что может быть не просто чистый просмотр содержимого файла, как это сделано в приведённой функции MyRead(). В простейшем случае для посимвольного анализа прочитанного из файла текста внутри цикла кроме вывода символа необходимо записать один или несколько операторов для анализа символа. Например, для подсчёта количества букв алфавита верхнего или нижнего регистра необходимо в цикле записать

if (isalpha (ch)) k++;,

а перед заголовком цикла int k=0;

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

В головной функции вывели простое меню, которое позволяет в цикле вызывать функции для работы с файлом в любом порядке и любое количество раз. Для начального создания файла надо ввести число 1. Затем можем просмотреть созданный файл (введём 2), добавить в конец одну или несколько строк символов (введём 3) и повторно можем ещё раз вывести измененный файл на экран, введя повторно число 2. Чтобы прекратить выполнение программы, надо ввести число 0.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: