Использование fread() и fwrite()Как только файл открыт для работы с двоичными данными, fread() и fwrite() соответственно могут читать и записывать информацию любого типа. Например, следующая программа записывает в дисковый файл данные типов double, int и long, a затем читает эти данные из того же файла. Обратите внимание, как в этой программе при определении длины каждого типа данных используется функция sizeof(). /* Запись несимвольных данных в дисковый файл и последующее их чтение. */#include < stdio.h> #include < stdlib.h> int main(void){ FILE *fp; double d = 12.23; int i = 101; long l = 123023L; if((fp=fopen(" test", " wb+"))==NULL) { printf(" Ошибка при открытии файла.\n"); exit(1); } fwrite(& d, sizeof(double), 1, fp); fwrite(& i, sizeof(int), 1, fp); fwrite(& l, sizeof(long), 1, fp); rewind(fp); fread(& d, sizeof(double), 1, fp); fread(& i, sizeof(int), 1, fp); fread(& l, sizeof(long), 1, fp); printf(" %f %d %ld", d, i, l); fclose(fp); return 0; }Как видно из этой программы, в качестве буфера можно использовать (и часто именно так и делают) просто память, в которой размещена переменная. В этой простой программе значения, возвращаемые функциями fread() и fwrite(), игнорируются. Однако на практике эти значения необходимо проверять, чтобы обнаружить ошибки. Одним из самых полезных применений функций fread() и fwrite() является чтение и запись данных пользовательских типов, особенно структур. Например, если определена структура struct struct_type { float balance; char name[80]; } cust;то следующий оператор записывает содержимое cust в файл, на который указывает fp: fwrite(& cust, sizeof(struct struct_type), 1, fp);Кроме основных функций ввода/вывода, о которых шла речь, в системе ввода/вывода языка С также имеются функции fprintf() и fscanf(). Эти две функции, за исключением того, что предназначены для работы с файлами, ведут себя точно так же, как и printf() и scanf(). Прототипы функций fprintf() и fscanf() следующие: int fprintf(FILE * уф, const char * управляющая_строка,...); int fscanf(FILE * уф, const char * управляющая_строка,...);где уф — указатель файла, возвращаемый в результате вызова fopen(). Операции ввода/вывода функции fprintf() и fscanf() выполняют с тем файлом, на который указывает уф. В качестве примера предлагается рассмотреть следующую программу, которая читает с клавиатуры строку и целое значение, а затем записывает их в файл на диске; имя этого файла — TEST. После этого программа читает этот файл и выводит информацию на экран. После запуска программы проверьте, каким получится файл TEST. Как вы и увидите, в нем будет вполне удобочитаемый текст. /* пример использования fscanf() и fprintf() */#include < stdio.h> #include < io.h> #include < stdlib.h> int main(void){ FILE *fp; char s[80]; int t; if((fp=fopen(" test", " w")) == NULL) { printf(" Ошибка открытия файла.\n"); exit(1); } printf(" Введите строку и число: "); fscanf(stdin, " %s%d", s, & t); /* читать с клавиатуры */ fprintf(fp, " %s %d", s, t); /* писать в файл */ fclose(fp); if((fp=fopen(" test", " r")) == NULL) { printf(" Ошибка при открытии файла.\n"); exit(1); } fscanf(fp, " %s%d", s, & t); /* чтение из файла */ fprintf(stdout, " %s %d", s, t); /* вывод на экран */ return 0; }Маленькое предупреждение. Хотя читать разносортные данные из файлов на дисках и писать их в файлы, расположенные также на дисках, часто легче всего именно с помошью функций fprintf() и fscanf(), но это не всегда самый эффективный способ выполнения операций чтения и записи. Так как данные в формате ASCII записываются так, как они должны появиться на экране (а не в двоичном виде), то каждый вызов этих функций сопряжен с определенными накладными расходами. Поэтому, если надо заботиться о размере файла или скорости, то, скорее всего, придется использовать fread() и fwrite().
|