Еще один способ чтения и записи информации в файлах представляют функции 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