fwrite y fread son funciones de E/S basadas en registros. Las funciones fread y fwrite generalmente se utilizan para la entrada y salida de archivos binarios.

#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);

Valor de retorno: el número de registros leídos o escritos. En caso de éxito, el número de registros devuelto es igual a nmemb. Si ocurre un error o se llega al final del archivo al leer, el número de registros devuelto es menor que nmemb, y también puede devolver 0.

fread y fwrite se usan para leer y escribir registros. Aquí, un registro se refiere a una secuencia de bytes de longitud fija, como un int, una estructura o una matriz de longitud fija. El parámetro size indica la longitud de un registro, y nmemb indica cuántos registros se van a leer o escribir. Estos registros se almacenan de forma contigua en el espacio de memoria señalado por ptr, ocupando un total de size * nmemb bytes. fread lee size * nmemb bytes del archivo stream y los guarda en ptr, mientras que fwrite escribe los size * nmemb bytes de ptr en el archivo stream.

nmemb es el número de registros solicitados para leer o escribir. El número de registros devuelto por fread y fwrite puede ser menor que el número especificado por nmemb. Por ejemplo, si la posición actual de lectura/escritura está a una longitud de registro del final del archivo, y se llama a fread con nmemb igual a 2, el valor de retorno será 1. Si la posición actual de lectura/escritura ya está al final del archivo, o si ocurre un error al leer el archivo, fread devuelve 0. Si ocurre un error al escribir el archivo, el valor de retorno de fwrite será menor que el valor especificado por nmemb. El siguiente ejemplo consta de dos programas: un programa guarda la estructura en un archivo, y el otro lee la estructura del archivo.

#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);  

Código de referencia de fwrite y fread:

Código del archivo 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;
}

Código del archivo 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

Se descubre que el archivo generado recfile no se puede abrir directamente.

Causa:Tomamos unastruct record estructura como un registro. Debido a que hay bytes de relleno en la estructura, cada registro ocupa 16 bytes, y al escribir dos registros en el archivo ocupan un total de 32 bytes. El archivo recfile generado por este programa es un archivo binario, no un archivo de texto, porque no solo contiene datos de tipo carácter, sino también datos enteros 24 y 28 (que se muestran en octal como 030 y 034 en la salida del comando od).

Nota: los programas que leen y escriben estructuras directamente en archivos no son portables. Si se compila y ejecuta el programa writebin.c en una plataforma, se copia el archivo recfile generado a otra plataforma, y allí se compila y ejecuta el programa readbin.c, no se puede garantizar que el contenido del archivo se lea correctamente, porque diferentes plataformas pueden tener diferente endianness (y por lo tanto almacenar los datos enteros de manera diferente), y la forma de relleno de las estructuras también puede diferir (por lo tanto, el número de bytes que ocupa la misma estructura puede ser diferente, y la posición del miembro age después del miembro name también puede ser diferente). Al leer el contenido del archivo recfile con el programa readrec, se demuestra que el programa writerec efectivamente escribió los registros correctamente en recfile.

El contenido leído de recfile es el siguiente:

Name1: Ken    Age1: 24
Name2: Knuth  Age2: 28

Ejemplos de aplicación de fwrite y fread:

1. Escribir una cadena en un archivo:

char *str="hello,I am a test program!";  
fwrite(str,sizeof(char),strlen(str),fp)  

2. Escribir una matriz de caracteres en un archivo:

char str[]={'a','b','c','d','e'};  
fwrite(str,sizeof(char),sizeof(str),fp)  

3. Escribir una matriz de enteros en un archivo:

int a[]={12,33,23,24,12};

Primero calcular el número de elementos del array nmemb, luego

fwrite(a,sizeof(int),nmemb,fp)

Nota: como el archivo generado por el programa es un archivo binario y no un archivo de texto, por lo tanto, en diferentes máquinas, la representación de los enteros es diferente, por lo que el archivo generado no se puede abrir directamente. Se puede usar la función fread para verificar si los datos se han escrito en el archivo.

Dirección original: http://purpleroom.blog.sohu.com/133812394.html