Форматируемый ввод-вывод
Еще один способ чтения и записи информации в файлах представляют функции fprintf() и fscanf(). Они позволяют отформатировать записываемые и считываемые данные соответственно.
Функция fprintf() имеет следующий прототип:
1
int fprintf(указатель_на_поток, строка_форматирования, список_аргументов);
Эта функция записывает данные, передаваемые в качестве третьего параметра, в файл с учетом форматирования, определяемого строкой форматирования. Первый параметр представляет указатель на файловый поток, в который производится запись.
Строка форматирования и передача в нее значений определяются также, как и в случае с функцией printf()
Например, запишем в файл массив структур:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
struct person
{
char name[20];
int age;
};
int main(void)
{
char * filename = "D://users.dat";
struct person people[] = { "Tom", 23, "Alice", 27, "Bob", 31, "Kate", 29 };
int n = sizeof(people)/sizeof(people[0]);
FILE *fp;
if ((fp = fopen(filename, "w")) == NULL)
{
perror("Error occured while opening file");
return 1;
}
for(int i=0; i<n; i++)
{
fprintf(fp, "%s %d\n", people[i].name, people[i].age);
}
fclose(fp);
return 0;
}
Каждая структура имеет два поля - строковое поле name и числовое поле age. Поэтому строка форматирования принимает соответствующие спецификаторы: "%s %d\n".
После записи мы получим текстовый файл users.dat, который сможем просмотреть в любом текстовом редакторе.
Для чтения данных в определенном формате применяется функция fscanf(), которая имеет следующий прототип:
1
int fscanf(указатель_на_поток, строка_форматирования, список_аргументов);
По факту эта функция похожа на функцию scanf(), которая используется для ввода с консоли, только теперь вод осуществляется из файла, указатель на который передается в качестве первого параметра.
Функция возвращает числовое значение. Если достигнут конец файла, то функция возвращает значение EOF.
Например, считаем и выведем на консоль ранее записанные в файл users.dat данные:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
struct person
{
char name[20];
int age;
};
int main(void)
{
char * filename = "D://users.dat";
FILE *fp;
char name[20];
int age;
if ((fp = fopen(filename, "r")) == NULL)
{
perror("Error occured while opening file");
return 1;
}
while((fscanf(fp, "%s %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