Основы программирования

Форматный ввод-вывод: функции fscanf и fprintf


В отличие от функции бинарного ввода fread, которая вводит байты из файла без всякого преобразования непосредственно в память компьютера, функция форматного ввода fscanf предназначена для ввода информации с преобразованием ее из текстового представления в бинарное. Пусть информация записана в текстовом файле в привычном для человека виде (т.е. так, что ее можно прочитать или ввести в файл, используя текстовый редактор). Функция fscanf читает информацию из текстового файла и преобразует ее во внутреннее представление данных в памяти компьютера. Информация о количестве читаемых элементов, их типах и особенностях представления задается с помощью формата. В случае функции ввода формат - это строка, содержащая описания одного или нескольких вводимых элементов. Форматы, используемые функцией fscanf, аналогичны применяемым функцией scanf, они уже неоднократно рассматривались (см. раздел 3.5.4). Каждый элемент формата начинается с символа процента "%". Наиболее часто используемые при вводе форматы приведены в таблице:

%dцелое десятичное число типа int (d - от decimal)
%lfвещ. число типа double (lf - от long float)
%cодин символ типа char
%sввод строки. Из входного потока выделяется слово, ограниченое пробелами или символами перевода строки '\n'. Слово помещается в массив символов. Конец слова отмечается нулевым байтом.

Прототип функции fscanf выглядит следующим образом:

int fscanf(FILE *f, const char *format, ...);

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

int n, m; double a; char c; char str[256]; FILE *f; . . . fscanf(f, "%d", &n); // Ввод целого числа fscanf(f, "%lf", &a); // Ввод вещественного числа fscanf(f, "%c", &c); // Ввод одного символа fscanf(f, "%s", str); // Ввод строки (выделяется очередное // слово из входного потока) fscanf(f, "%d%d", &n, &m); // Ввод двух целых чисел


Функция fscanf возвращает число успешно введенных элементов. Таким образом, возвращаемое значение всегда меньше или равно количеству процентов внутри форматной строки (которое равно числу фактических аргументов минус 2).

Функция fprintf используется для форматного вывода в файл. Данные при выводе преобразуются в их текстовое представление в соответствии с форматной строкой. Ее отличие от форматной строки, используемой в функции ввода fscanf, заключается в том, что она может содержать не только форматы для преобразования данных, но и обычные символы, которые записываются без преобразования в файл. Форматы, как и в случае функции fscanf, начинаются с символа процента "%". Они аналогичны форматам, используемым функцией fscanf. Небольшое отличие заключается в том, что форматы функции fprintf позволяют также управлять представлением данных, например, указывать количество позиций, отводимых под запись числа, или количество цифр после десятичной точки при выводе вещественного числа. Некоторые типичные примеры форматов для вывода приведены в следующей таблице:

%dвывод целого десятичного числа
%10dвывод целого десятичного числа, для записи числа отводится 10 позиций, запись при необходимости дополняется пробелами слева
%lfвывод вещественного число типа double в форме с фиксированной десятичной точкой
%.3lfвывод вещественного число типа double с печатью трёх знаков после десятичной точки
%12.3lfвывод вещественного число типа double с тремя знаками после десятичной точки, под число отводится 12 позиций
%cвывод одного символа
%sконец строки, т.е. массива символов. Конец строки задается нулевым байтом
Прототип функции fprintf выглядит следующим образом:

int fprinf(FILE *f, const char *format, ...);

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


Для примера рассмотрим небольшую программу, выводящую данные в файл "tmp.dat":

#include <stdio.h> // Описания функций ввода вывода #include <math.h> // Описания математических функций #include <string.h> // Описания функций работы со строками

int main() { int n = 4, m = 6; double x = 2.; char str[256] = "Print test"; FILE *f = fopen("tmp.dat", "wt"); // Открыть файл if (f == 0) { // для записи perror("Не могу открыть файл для записи"); return 1; // Завершить программу с кодом ошибки } fprintf(f, "n=%d, m=%d\n", m, n); fprintf(f, "x=%.4lf, sqrt(x)=%.4lf\n", x, sqrt(x)); fprintf( f, "Строка \"%s\" содержит %d символов.\n", str, strlen(str) ); fclose(f); // Закрыть файл return 0; // Успешное завершение программы }

В результате выполнения этой программы в файл "tmp.dat" будет записан следующий текст:

n=6, m=4 x=2.0000, sqrt(x)=1.4142 Строка "Print test" содержит 10 символов.

В последнем примере форматная строка содержит внутри себя двойные апострофы. Это специальные символы, выполняющие роль ограничителей строки, поэтому внутри строки их надо экранировать (т.е. защищать от интерпретации как специальных символов) с помощью обратной косой черты \, которая, напомним, в системе Unix и в языке Си выполняет роль защитного символа. Отметим также, что мы воспользовались стандартной функцией sqrt, вычисляющей квадратный корень числа, и стандартной функцией strlen, вычисляющей длину строки.


Содержание раздела