Пример 2. Работа с текстовым файлом построчно с помощью стандартных функций fputs и fgets.
const size =80; char str[size]; FILE *tf;
//Функция для построчного создания текстового файла с помощью fputs.
void MyCreate()
{ clrscr();
if ((tf=fopen("d:\\ANA\\cpp\\2005_06\\ FileStr\\textf2.dat ","w"))==NULL)
{ printf("Error\n"); return; }
else printf("File is opened for creating\n");
puts("@@@ -- exit\n");
gets(str); // Вводим первую строку с экрана вне цикла.
do {
/* Записываем строку из оперативной памяти (str) на внешнее устройство в файл (tf). */
fputs(str,tf);
/* После каждой строки в файл записываем символ новой строки */
fputc('\n',tf);
/* В цикле вводим следующие строки с экрана */
gets(str);
}
while(!strstr(str,"@@@"));
fclose(tf);
}
/* Функция int fputs (const char *str, FILE *stream) записывает содержимое строки, на которую указывает str, в заданный поток. Нуль в конце строки не записывается. Символ новой строки записывается, чтобы “помочь” функции чтения строки определить её конец(см. описание fgets). В случае успешной записи возвращается последний записанный символ, а в случае неудачи — EOF. При работе с потоком в текстовом режиме могут иметь место преобразования символов (см. 1.1). Для двоичного режима такого преобразования символов нет и строка переписывается в файл “один к одному”.
|
|
Для выхода из цикла, то есть, чтобы прекратить создание файла, необходимо ввести не менее трёх подряд идущих символа “@” (см. описание строковой функции strstr).*/
// Функция для добавления в конец текстового файла
void MyAppend()
{ clrscr();
if ((tf=fopen("d:\\ANA\\cpp\\2005_06\\ FileStr\\textf2.dat ","a"))==NULL)
{ printf("Error\n"); return;
}
else printf("File is opened for appending\n");
puts("@@@ -- exit\n");
gets(str);
do { fputs(str,tf);
fputc('\n',tf);
gets(str);
}
while(!strstr(str,"@@@"));
fclose(tf);
}
/* Как видим, эта функция почти ничем не отличается от предыдущей функции создания файла. Только при открытии файла вместо режима “ w ” указан “ a ”, так как мы открываем файл для добавления в его конец.
Функция для построчного просмотра и анализа созданного файла. В прочитанном из файла тексте найти количество гласных букв.*/
void MyRead()
{ clrscr();
if ((tf=fopen("d:\\ANA\\cpp\\2004_05\\ FileStr\\textf2.dat ","r"))==NULL)
{ printf("Error\n"); return;
}
else printf("File is opened for reading\n");
int i,k=0;
while (fgets (str, size, tf)!=NULL)
{
/* Прочитали одну строку из файла и проверили результат операции чтения. */
printf("%s",str); // Вывод одной строки на экран.
// Посимвольный анализ одной прочитанной строки
for(int i=0; str[i]; i++)
if (strchr("aeyuio", str[i]))k++;
}
cout<<"\n "<<k<<'\n';
fclose (tf);
}
int main()
{ int flag;
do { cout<<"1 -- Create file\n"<<
"2 -- Look file\n"<<
"3 -- Append file\n"<<
"0 -- Exit\n";
cin>>flag;
switch (flag)
{ case 1: MyCreate(); break;
case 2: MyRead(); break;
case 3: MyAppend(); break;
case 0: return 0;
}
} while (1);
return 0;
}
Функция char * fgets (char *str, int num, FILE *stream) считывает до (num-1) символов из указанного потока и помещает их в массив символов, на который указывает str. Символы считываются до тех пор, пока не встретится символ “новая строка”, EOF или пока не будет прочитано (num-1) символов. В нашем случае чаще всего строка будет читаться, пока не встретится символ “новая строка”, который после каждой строки мы записывали в функции создания. Поэтому не обязательно, чтобы каждая строка содержала ровно 80 символов. По окончании считывания сразу после последнего считанного символа помещается нулевой символ. Символ “новая строка” также помещается в массив str.
|
|
В случае успешного чтения fgets возвращает прочитанную строку (в примере str), а при неудаче — NULL. В случае ошибки чтения содержимое массива, на который указывает str, не определено. При достижении конца файла также возвращается NULL, и это в нашем варианте использовалось в операторе цикла while. Каждый раз в цикле читается одна строка и результат этой операции, то есть указатель на строку, сравнивается на NULL. Если при очередной попытке чтения строки из файла будет достигнут его конец, то выражение в заголовке while станет ложным и мы выйдем из цикла.
Для проверки на конец файла можно также использовать функцию feof().
Головная функция аналогична примеру 1, поэтому её описание смотри в 2.1.