Форматируемый ввод-вывод

Последнее обновление: 09.01.2023

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