fwrite и fread — это функции ввода-вывода, которые работают в единицах записей. Функции fread и fwrite обычно используются для ввода и вывода двоичных файлов.
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
Возвращаемое значение: количество прочитанных или записанных записей. При успешном выполнении количество возвращённых записей равно nmemb. При ошибке или при достижении конца файла количество возвращённых записей меньше nmemb, также может возвращаться 0.
fread и fwrite используются для чтения и записи записей. Здесь запись — это последовательность байтов фиксированной длины, например int, struct или массив фиксированной длины. Параметр size задаёт длину одной записи, а nmemb указывает, сколько записей нужно прочитать или записать. Эти записи хранятся непрерывно в области памяти, на которую указывает ptr, и занимают в сумме size * nmemb байт. fread читает size * nmemb байт из файлового потока и сохраняет их в ptr, а fwrite записывает size * nmemb байт из ptr в файловый поток.
nmemb — это количество записей, запрошенных для чтения или записи. Количество записей, возвращаемых fread и fwrite, может быть меньше количества записей, указанного в nmemb. Например, если текущая позиция чтения/записи отстоит от конца файла всего на длину одной записи и при вызове fread указано nmemb = 2, возвращаемое значение будет 1. Если текущая позиция чтения/записи уже находится в конце файла или при чтении файла возникает ошибка, fread возвращает 0. Если при записи файла возникает ошибка, возвращаемое значение fwrite меньше значения, указанного в nmemb. Следующий пример состоит из двух программ: одна программа сохраняет struct в файл, а другая читает struct из файла.
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
Справочный код fwrite и fread:
код файла writerec.c
/* -------------------writerec.c--------------- */
#include <stdio.h>
#include <stdlib.h>
struct record {
char name[10];
int age;
};
int main(void)
{
struct record array[2] = {{"Ken", 24}, {"Knuth", 28}};
FILE *fp = fopen("d:/test.txt", "w");
if (fp == NULL) {
perror("Open file recfile");
exit(1);
}
fwrite(array, sizeof(struct record), 2, fp);
fclose(fp);
return 0;
}
код файла readrec.c:
/* -------------------readrec.c----------------- */
#include <stdio.h>
#include <stdlib.h>
struct record {
char name[10];
int age;
};
int main(void)
{
struct record array[2];
FILE *fp = fopen("d:/test.txt", "r");
if (fp == NULL) {
perror("Open file recfile");
exit(1);
}
fread(array, sizeof(struct record), 2, fp);
printf("Name1: %s\tAge1: %d\n", array[0].name, array[0].age);
printf("Name2: %s\tAge2: %d\n", array[1].name, array[1].age);
fclose(fp);
return 0;
}
$ gcc writerec.c -o writerec $ gcc readrec.c -o readrec
Было обнаружено, что созданный файл recfile нельзя открыть напрямую.
Причина:Мы рассматриваемstruct record как одну запись. Поскольку структура содержит байты заполнения, каждая запись занимает 16 байт, и запись двух записей в файл занимает в общей сложности 32 байта. Файл recfile, созданный этой программой, является двоичным файлом, а не текстовым, потому что он хранит не только символьные данные, но и целочисленные данные 24 и 28 (отображаемые в восьмеричном виде как 030 и 034 в выводе команды od).
Обратите внимание, что программы, которые напрямую читают и записывают структуры в файлах, непереносимы. Если вы скомпилируете и запустите программу writebin.c на одной платформе, скопируете созданный файл recfile на другую платформу и скомпилируете и запустите программу readbin.c на той платформе, вы не можете гарантировать, что содержимое файла будет прочитано правильно, потому что на разных платформах может быть разный порядок байтов (и, следовательно, целочисленные данные хранятся по-разному), а заполнение структур также может различаться (поэтому количество байтов, занимаемых одной и той же структурой, может отличаться, и положение члена age после члена name также может отличаться). Использование программы readrec для чтения содержимого файла recfile демонстрирует, что программа writerec действительно успешно записала записи в recfile.
Содержимое, прочитанное из recfile, выглядит следующим образом:
Name1: Ken Age1: 24 Name2: Knuth Age2: 28
Примеры применения fwrite и fread:
1. Запись строки в файл:
char *str="hello,I am a test program!"; fwrite(str,sizeof(char),strlen(str),fp)
2. Запись массива символов в файл:
char str[]={'a','b','c','d','e'};
fwrite(str,sizeof(char),sizeof(str),fp)
3. Запись массива целых чисел в файл:
int a[]={12,33,23,24,12};
Сначала вычислите количество элементов массива nmemb, затем
fwrite(a,sizeof(int),nmemb,fp)
Примечание: Поскольку файл, созданный программой, является двоичным файлом, а не текстовым, целые числа на разных машинах представляются по-разному, поэтому созданный файл нельзя открыть напрямую. Вы можете использовать функцию fread, чтобы проверить, были ли данные записаны в файл.
Исходный URL: http://purpleroom.blog.sohu.com/133812394.html