Функции файловой системы языка С



 

№ п/п Имя функции Что делает
1. fopen() Открывает файл
2. fclose() Закрывает файл
3. putc() Записывает символ в файл
4. fputc() То же, что и putc()
5. getc() Читает символ из файла
6. fgetc() То же, что и getc()
7. fgets() Читает строку из файла
8. fputs() Записывает строку в файл
9. fseek() Устанавливает указатель текущей позиции на определенный байт файла
10. ftell() Возвращает текущее значение указателя текущей позиции в файле
11. fprintf() Для файла то же, что printf() для консоли
12. fscanf() Для файла то же, что scanf() для консоли
13. feof() Возвращает значение true (истина), если достигнут конец файла
14. ferror() Возвращает значение true (истина), если произошла ошибка
15. rewind() Устанавливает указатель текущей позиции в начало файла
16. remove() Стирает файл
17. fflush() Дозапись потока в файл

 

Для приведенных функций требуется подключить заголовок <stdio.h>. Запись или чтение из файла осуществляются с помощью указателя файла. Указатель файла – это указатель на структуру типа FILE. Для объявления переменной–указателя файла, например, *fp, используется следующий оператор:

FILE *fp;

Ключевое слово FILE определяет собой своеобразный тип данных, а указатель *fp указывает на этот тип.

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

Открытие файла осуществляется с помощью функции fopen(), которая открывает поток и связывает с этим потоком определенный файл. Прототип функции fopen() такой:

 

FILE *fopen(const char *file_name, const char *mode);

В прототипе функции fopen() формальные переменные имеют следующий смысл:

file_name – это имя файла с заданным расширением и возможным путем расположения, mode – режим работы файла: чтение, запись и т.д.

В табл. 8.2 приводятся допустимые значения режима для функции fopen().

Таблица 8.2.

Допустимые значения режима функции fopen()

 

№ п/п Режим Что означает
1. r Открыть текстовый файл для чтения
2. w Создать текстовый файл для записи
3. a Добавить в конец текстового файла
4. rb Открыть двоичный файл для чтения
5. wb Создать двоичный файл для записи
6. ab Добавить в конец двоичного файла
7. r+ Открыть текстовый файл для чтения/записи
8. w+ Создать текстовый файл для чтения/записи
9. a+ Добавить в конец текстового файла или создать текстовый файл для чтения/записи
10. r+b Открыть двоичный файл для чтения/записи
11. w+b Создать двоичный файл для чтения/записи
12. a+b Добавить в конец двоичного файла или создать двоичный файл для чтения/записи

Например, для записи в файл с именем (и расширением) data.txt на диск D следует использовать такие объявление и операции:

FILE *fp;fp = fopen("D: \\data.txt", "w");fprintf(fp, "\n\t hello, world\n");fclose(fp);

В приведенном фрагменте С++ – кода функция fclose() закрывает поток, который был открыт с помощью вызова функции fopen(). Функция fprintf() осуществляет форматную запись (в данном случае строку hello, world) в файл. Все манипуляции с файлом происходят между функциями fopen() и fclose(). Режим функции fopen() задается строкой "w", которая обеспечивает создание текстового файла для записи. Это означает, что файл data.txt создается на диске D и в него записывается строка hello, world с отступом от верхнего края и с отступом (табуляцией) от левого края.

Прототип функции fclose() следующий:

 

int fclose(FILE *fp);

В приведенной записи *fp – указатель файла, возвращенный в результате вызова функции fopen(). Возвращение нуля означает успешную операцию закрытия. В случае же ошибки возвращается EOF. Обычно отказ при выполнении функции fclose() происходит только тогда, когда диск был преждевременно удален из дисковода или на диске не осталось свободного места.

Правомочность открытия файла с помощью функции fopen() обычно подтверждается после проверки какой-либо ошибки, например, когда на диске нет места для записи или неправильного имени диска, причем эти ошибки будут обнаружены до того, как программа попытается в этот файл что-либо записать. Поэтому приведенный фрагмент С++ – кода будет правильным, если производится проверка возможности открытия файла:

 

FILE *fp; if ((fp = fopen("D:\\data.txt", "w")) == NULL) { //exit(1);printf("\n\t Error! Can not open file\n ");printf("\n Press any key: ");_getch(); return 0; }fprintf(fp, "\n\t hello, world\n");fclose(fp);

 

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

Функции для работы с текстовыми файлами удобно использовать при создании текстовых файлов, ведении файлов-протоколов и т.п. Но при создании баз данных целесообразно использовать функции для работы с бинарными файлами: fwrite() и fread(). Эти функции без каких-либо изменений копируют выделенный блок данных из оперативной памяти в файл и, соответственно, из файла – в память.

При записи или чтении суффикс "t" открывает файл в текстовом режиме. В этом режиме символ CTRL+Z (символ с кодом 26) обрабатывается как символ конца файла. Кроме того, комбинации символов перевода строки и возврата каретки преобразуются в единственный символ перевода строки ('\n') при вводе, и символы перевода строки преобразуются в комбинации символов перевода строки и возврата каретки при выводе.

Суффикс "b" открывает файл в бинарном режиме, преобразования символов перевода строки и возврата каретки не производятся.

 

FILE *fp; if ((fp = fopen("D:\\data.txt", "w")) == NULL) { //exit(1); printf("\n\t Error! Can not open file\n "); printf("\n Press any key: "); _getch(); return -1; }fprintf(fp, "\n\t hello, world\n");fclose(fp);

Практическая часть

Пример 1. Напишите программу заполнения матрицы размера n m нечетными целыми числами с выводом результата на консоль и в текстовый файл. Размеры матрицы и начальное нечетное число задаются пользователем с клавиатуры.

Программный код решения примера:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h>#include <stdlib.h> int main(void) {int i, j, x, xi, n, m, *matr;FILE *fid;char str[] = "D:\\data.txt"; // месторасположение файлаif ((fid = fopen(str, "w")) == NULL){ printf("\n\t The file could not be opened.\n "); printf("\n Press any key: ");_getch(); return 0; } printf("\n\t Enter the number of lines: "); scanf_s("%d", &n);printf("\t Enter the number of columns: "); scanf_s("%d", &m);printf("\t Enter the odd number: "); scanf_s("%d", &x);xi = x; matr = (int *)calloc(n*m, sizeof(int));// Заполнение матрицы целыми числамиfor (i = 0; i < n; ++i)for (j = 0; j < m; ++j){matr[i*m + j] = x; x += 2; } printf("\n\t Matrix (%d x %d), initial number: %d\n", n, m, xi);fprintf(fid, "\r\n\t Matrix (%d x %d), initial number: %d\r\n", n, m, xi);for (i = 0; i < n; ++i){ printf("\n "); fprintf(fid, "\r\n "); for (j = 0; j < m; ++j){printf("%5d", matr[i*m + j]); fprintf(fid, "%5d", matr[i*m + j]); }} fclose(fid);printf("\n\n Result of record look in file %s\n", str); printf("\n Press any key: ");_getch();return 0; }

В программу включена препроцессорная директива #define... для устранения предупреждения о ненадежной работе функции fopen() в Visual Studio 2008.

Возможный результат выполнения программы показан на рис. 8.1.

 


Рис. 8.1. Заполнение матрицы нечетными числами

Текстовый файл с заполненной матрицей показан на рис. 8.2.

 


Рис. 8.2. Матрица нечетных чисел в текстовом файле

 

Примечание. В текстовом файле следует использовать моноширинный (равноширинный) шрифт, например, Courier New.

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

Для решения примера используем функции fprintf(), fgets(), atoi(), fscanf().

 

Программный код решения примера:

 

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h>#include <stdlib.h> #define n 4 // Число строк матрицы#define m 3 // Число столбцов матрицы#define N 123 // Число считываемых строк из текстового файла int main(void) { int i, j = 0; int A[n*m] = {1,2,3,4,5,6,7,8,9,10,11,12}; int B[n*m]; FILE *fid; char *str[] = {"aza","baza","qwerty"}; char str2[N][80]; // Буферный массив // Обнуление массива B[n*m] for (i = 0; i < n*m; ++i) B[i] = 0; if ((fid = fopen("D:\\data2.txt", "w")) == NULL){printf("\n\t The file could not be opened.\n ");printf("\n Press any key: "); _getch(); return 0; } // Запись в файл data2.txtfprintf(fid, "\n\t The lines are:\n");for (i = 0; i < m; ++i) fprintf(fid,"\t %s\n", str[i]); for (i = 0; i < n*m; ++i) fprintf(fid, " %3d", A[i]); fclose(fid); printf("\n\t From file \"data2.txt\":\n");if ((fid = fopen("D:\\data2.txt", "r")) == NULL){printf("\n\t The file could not be opened.\n ");printf("\n Press any key: "); _getch(); return 0; } // Чтение из файла data2.txtfor (i = 0; (fgets(str2[i], 80, fid)!= NULL) && (i < N); ++i) printf(" %s",str2[i]);fclose(fid); if ((fid = fopen("D:\\data2.txt", "r")) == NULL){printf("\n\t Error! You can not open the file \n ");printf("\n Press any key: "); _getch(); return 0; }// Повторное чтение из файла data2.txtfor (i = 0; fscanf (fid, "%s", str2[i])!= EOF; ++i) if (atoi(str2[i])){ B[j] = atoi(str2[i]); ++j; } fclose(fid); printf("\n\n\t The reconfigured array:\n");for (i = 0; i < n; ++i) {printf("\n\t");for (j = 0; j < m; ++j)printf("%5d", B[i*m+j]); } printf("\n\n Press any key: ");_getch(); return 0; }

 

Для форматированной записи в текстовый файл и чтения из файла применены массивы указателей *str[], str2[123][80]. Чтение из файла одномерного массива целых чисел выполняется с помощью функции atoi(), значения целых чисел заносятся сначала в одномерный массив B[n*m]. После закрытия файла data2.txt одномерный массив B[n*m] выводится на консоль в виде двухмерной матрицы размера 4 3. Форматированная запись строк и одномерного массива в файл data2.txt производится с помощью функции fprintf(). Первое чтение информации из текстового файла производится с помощью функции fgets(), что позволяет практически точно копировать расположение строк текстового файла на консоль (дисплей). Функция fscanf() используется для форматированного чтения информации из текста с последующим выделением целых чисел с помощью функции atoi().

Возможный результат выполнения программы показан на рис. 8. 3.

 


Рис. 8.3. Содержимое текстового файла и преобразованного массива

 

Пример 3. Напишите программу добавления слов в текстовый файл с контролем на консоли.

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

Для программного решения примера используем функции файлового ввода/вывода fprintf(), fgets() и rewind(). Кроме того, подключим библиотеку locale.h и объявим прототип функции, что позволит использовать шрифты русского алфавита:>

#include <locale.h> setlocale(LC_ALL, "Russian");

или

setlocale(LC_ALL, ".1251");//кодовая страница Windows–1251

 

Программный код решения примера:

 

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <conio.h>#include <locale.h>#define MAX 40 int main(void) { FILE *fid; char words[MAX+1];char str_name[] = "D:\\data3.txt";// Прототип функции поддержки русских шрифтов setlocale(LC_ALL, "Russian"); if ((fid = fopen(str_name, "a+")) == NULL){fprintf(stdout, "\n\t Файл не может быть открыт \"%s\".\n ", str_name); printf("\n Нажмите любую клавишу: ");_getch(); return -1; }printf("\n\t Введите слова для включения их в файл \"%s\"\n\t\и нажмите клавишу Enter в начале строки для завершения ввода\n\t: ", str_name); // Запись в файл data3.txtwhile (gets_s(words, MAX)!= NULL && words[0]!= '\0'){printf("\t: "); fprintf(fid," %s\n", words); } puts("\t Содержимое файла:");// Устанавливает указатель текущей позиции в начало файлаrewind(fid); // Сканирование файлаwhile (fgets(words, MAX, fid)!= '\0') printf("\t%s", words); if (fclose(fid)!= 0)fprintf(stderr, "\n\t Ошибка при закрытии файла \"%s\"\n", str_name); printf("\n\n Нажмите любую клавишу (Press any key): "); _getch(); return 0; }

В программе введены две проверки: на открытие файла if (... == NULL) и на закрытие файла if (...!= 0). Эти проверки позволяют исключить аварийный выход из программы. Использование в функции форматного вывода fprintf() ключевого слова stdout позволяет выводить сообщения на консоль – дисплей пользователя.

Вместо стандартной функции gets() использована функция gets_s(), которую поддерживает MS Visual Studio. При работе в MS Visual Studio с функцией gets() появляются предупреждения (которыми в общем случае можно пренебречь). Предупреждения возникают и при работе с функцией fopen(). Вместо нее можно использовать fopen_s() в следующем формате записи:

 

fopen_s(&fid, "D:\\data3.txt","a+");

Тогда проверку на открытие файла следует изменить, например:

 

if (fopen_s(&fid, "D:\\data3.txt","a+")){fprintf(stdout, "\n\t Ошибка! Не удается открыть файл \"data3.txt\".\n ");printf("\n Нажмите любую клавишу: ");_getch(); return -1; }

Если файл data3.txt сохранить, то при последующих выполнениях программы в этот файл будут дописывать данные. Это обеспечивает режим "a+" функции fopen().

Возможный результат выполнения программы показан на рис. 8. 4.


Рис. 8.4. Пример записи в файл и чтения из файла

Примечание. Для данной программы формат записи функции fscanf():

fscanf(fid, "%s", words);

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

Для решения примера используем функции fseek() и ftell().

 

Программный код решения примера:

 

#include <stdio.h>#include <conio.h>#define MAX 79#define file "D:\\data6.txt" // запись в прямом порядке#define file2 "D:\\data66.txt" // запись в обратном порядке int main(void) { char ch, str[MAX+1]; long n, m; FILE *fid, *fid2; if (fopen_s(&fid, file, "w")) {fprintf(stdout, "\n\t The file could not be opened.\n ");printf("\nPress any key: ");_getch(); return 0; } printf("\n\t Enter a few lines and press Enter to complete before the new line\n\t: "); // Запись в файл data6.txtwhile (gets_s(str, MAX)!= NULL && str[0]!= '\0'){ printf("\t: "); fprintf(fid," %s\n", str); } fclose(fid); if (fopen_s(&fid, file, "r")) {fprintf(stdout, "\n\t File could not be opened.\n");printf("\n Press any key: ");_getch(); return 0; } if (fopen_s(&fid2, file2, "w")) {fprintf(stdout, "\n\t File could not be opened.\n");printf("\n Press any key: ");_getch(); return 0; } //Переход в конец файлаfseek(fid, 0L, SEEK_END);m = ftell(fid); for (n = 1L; n <= m; n++) {fseek(fid, -n, SEEK_END);ch = getc(fid); if (ch!= '\n') { printf(" "); putchar(ch); fprintf(fid2, " "); putc(ch, fid2); } } // End forputchar('\n'); fclose(fid);fprintf(fid2, "%c", '\n');fclose(fid2); printf("\n Result see the files, \"%s\" and \"%s\"\n", file, file2); printf("\n Press any key: "); _getch(); return 0; }

 

Функция fseek() имеет следующую форматную запись:

fseek(fid, 0L, SEEK_END);

Она определяет позицию со смещением в 0 байт от конца файла (именованная константа SEEK_END). Суффикс L означает тип long int.

Строка с функцией ftell() определяет количество байтов от начала до конца указанного файла. Это количество байтов записывается в переменную m:

m = ftell(fid);

 

Рассмотрим следующий программный цикл:

 

for (n = 1L; n <= m; n++) {fseek(fid, -n, SEEK_END);ch = getc(fid);if (ch!= '\n'){ printf(" "); putchar(ch); fprintf(fid2, " "); putc(ch, fid2); } } // End for

 

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

 

Возможные результаты выполнения программы показаны на рис. 8. 5 -рис. 8. 6.

 


Рис. 8.5. Результат обратного считывания информации из файла

 

 


Рис. 8.6. Результат записи информации в файл в обратном порядке

 

Пример 5. Создать таблицу табуляции функции

с использованием оператора While на отрезке [-2; 5] с шагом 0,8.

Результат записать в текстовый файл под именем «data_pr.txt». Произвести чтение данных из файла «data_pr.txt» и вывод их на консоль.

Программный код решения примера:

 

// Восьмая программа на языке Си++

// Автор Загребельный С.Л.

#define _CRT_SECURE_NO_WARNINGS

#define MAX 79

#include <stdio.h>

#include <conio.h>

#define _USE_MATH_DEFINES

#include <math.h>

#include <limits.h>

#include <float.h>

#include <locale.h>

 

int main(void) {

FILE *fid;

double xn, xk, xh, a, x, y;

int i;

char str_name[] = "D:\\data_pr.txt";

char words[MAX+1];

setlocale(LC_ALL, "Russian");

if ((fid = fopen(str_name, "w")) == NULL)

{fprintf(stdout, "\n\t Файл не может быть открыт \"%s\".\n ", str_name);

printf("\n Нажмите любую клавишу: ");

_getch(); return 0; }

 

printf("\n\t Введите xn= ");

scanf_s("%lf", &xn);

printf("\t Введите Xk= ");

scanf_s("%lf", &xk);

printf("\t Введите Xh= ");

scanf_s("%lf", &xh);

printf("\t Введите a= ");

scanf_s("%lf", &a);

x=xn;

while (x <= xk) {

if (x<=0){ y=2*x+2;}else {

if (x<=a) {y=sqrt(x+3);}else{

if (x>a) {y=pow(cos(x+2),2);}}}

fprintf(fid,"\n\t %4.3f\t\t%4.3f\n", x,y);

x=x+xh;

}

fclose(fid);

printf("\n\t Чтение из файла \"data_pr.txt\":\n");

if ((fid = fopen("D:\\data_pr.txt", "r")) == NULL)

{printf("\n\t Файл не открывается.\n ");

printf("\n Нажмите любую клавишу: "); _getch(); return 0; }

 

puts("\t Содержимое файла:");

// Устанавливает указатель текущей позиции в начало файла

rewind(fid);

// Сканирование файла

while (fgets(words, MAX, fid)!= '\0')

printf("\t%s", words);

 

if (fclose(fid)!= 0)

fprintf(stderr, "\n\t Ошибка при закрытии файла \"%s\"\n", str_name);

fclose(fid);

printf("\n Press any key: ");

_getch();

return 0;

}

 

Рис. 8.7. Окно работы программы

 

 

Рис. 8.8. Результат записи информации в текстовый файл «data_pr.txt»

 


Дата добавления: 2015-12-20; просмотров: 20; Мы поможем в написании вашей работы!

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






Мы поможем в написании ваших работ!