Еще один способ чтения и записи информации в файлах представляют функции fprintf() и fscanf(). Они позволяют отформатировать записываемые и считываемые данные соответственно.
Функция fprintf() имеет следующий синтаксис:
int fprintf(указатель_на_поток, строка_форматирования, список_аргументов);
Эта функция записывает данные, передаваемые в качестве третьего параметра, в файл с учетом форматирования, определяемого строкой форматирования. Первый параметр представляет указатель на файловый поток, в который производится запись.
Строка форматирования и передача в нее значений определяются также, как и в случае с функцией printf()
Например, запишем в файл массив структур:
#include <stdio.h> struct person { char name[20]; int age; }; int main(void) { char * filename = "users.dat"; struct person people[] = { {"Tom", 23}, {"Alice", 27}, {"Bob", 31}, {"Kate", 29} }; // количество записываемых структур int n = sizeof(people)/sizeof(people[0]); FILE *fp = fopen(filename, "w"); if (!fp) { printf("Error occured while opening file\n"); return 1; } for(int i=0; i < n; i++) { fprintf(fp, "%s %d\n", people[i].name, people[i].age); } fclose(fp); printf("File has been written\n"); return 0; }
Каждая структура имеет два поля - строковое поле name и числовое поле age. Поэтому строка форматирования принимает соответствующие спецификаторы:
"%s %d\n"
.
После записи мы получим текстовый файл users.dat, который сможем просмотреть в любом текстовом редакторе.
Для чтения данных в определенном формате применяется функция fscanf(), которая имеет следующий синтаксис:
int fscanf(указатель_на_поток, строка_форматирования, список_аргументов);
По факту эта функция похожа на функцию scanf(), которая используется для ввода с консоли, только теперь вод осуществляется из файла, указатель на который передается в качестве первого параметра.
Функция возвращает числовое значение. Если достигнут конец файла, то функция возвращает значение EOF.
Например, считаем и выведем на консоль ранее записанные в файл users.dat данные:
#include <stdio.h> int main(void) { char * filename = "users.dat"; char name[20]; // для считывания имени int age; // для считывания возраста FILE *fp = fopen(filename, "r"); if (!fp) { printf("Error occured while opening file\n"); return 1; } while((fscanf(fp, "%20s %d\n", name, &age))!=EOF) { printf("%s %d\n", name, age); } fclose(fp); return 0; }
Для считывания данных здесь определены вспомогательные переменные name и age. И при вызове функции fscanf в качестве списка аргументов передаются
адреса этих переменных. Кроме того, надо отметить, что строка форматирования совпадает со строкой, которая передавалась в предыдущем примере при записи в файл:
"%s %d\n"
.
В итоге пока при считывании не будет достигнут конец файла и функция не вернет значение EOF, она будет считывать данные в переменные name и age, которые затем будут выводиться на консоль. В итоге мы получим следующий консольный вывод:
Tom 23 Alice 27 Bob 31 Kate 29