fwrite
是 C 语言标准库中用于二进制数据写入的重要函数,它可以将数据块直接写入文件。
函数原型
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
参数说明
参数 | 类型 | 说明 |
ptr | const void* | 指向要写入数据的指针(数据来源) |
size | size_t | 每个数据项的字节大小 |
nmemb | size_t | 要写入的数据项数量 |
stream | FILE* | 指向 FILE 对象的指针,指定要写入的文件流 |
返回值 | size_t | 成功写入的数据项数量(若与 nmemb 不同,则可能发生错误或到达文件末尾) |
基本使用步骤
- 打开文件(使用
fopen
以二进制写入模式) - 准备要写入的数据
- 调用
fwrite
写入数据 - 检查返回值确认写入是否成功
- 关闭文件(使用
fclose
)
示例代码
示例1:写入基本数据类型
#include <stdio.h>
int main()
{
FILE *fp = fopen("data.bin", "wb"); // 二进制写入模式
if (fp == NULL)
{
perror("open file error");
return 1;
}
int numbers[] = {10, 20, 30, 40, 50};
size_t elements_written = fwrite(numbers, sizeof(int), 5, fp);
if (elements_written != 5)
{
printf("write error, just write %zu elements\n", elements_written);
}
fclose(fp);
return 0;
}
示例2:写入结构体数据
#include <stdio.h>
#include <string.h>
typedef struct {
int id;
char name[50];
float score;
} Student;
int main() {
Student s = {1, "张三", 89.5};
FILE *fp = fopen("student.dat", "wb");
if (fp == NULL) {
perror("文件打开失败");
return 1;
}
size_t written = fwrite(&s, sizeof(Student), 1, fp);
if (written != 1) {
printf("写入结构体失败\n");
}
fclose(fp);
return 0;
}
示例3:写入多个结构体
#include <stdio.h>
typedef struct
{
char name[30];
int age;
} Person;
int main()
{
Person people[] = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35}};
FILE *fp = fopen("people.dat", "wb");
if (fp == NULL)
{
perror("file open error\n");
return 1;
}
size_t count = sizeof(people) / sizeof(Person);
size_t written = fwrite(people, sizeof(Person), count, fp);
if (written != count)
{
printf("just write %zu/%zu peoples\n", written, count);
}
printf("write %zu peoples\n", written);
fclose(fp);
return 0;
}
注意事项
- 文件打开模式:必须使用二进制模式("wb"、"ab"等),文本模式可能导致数据转换问题
- 数据对齐:写入的结构体/数据在内存中的布局会影响读取结果
- 字节序:在不同系统间传输二进制数据时需考虑字节序问题
- 返回值检查:务必检查
fwrite
返回值以确保数据完整写入 - 错误处理:使用
ferror
可以检测写入错误
if (fwrite(people, sizeof(Person), count, fp) != count)
{
if (feof(fp))
{
printf("reach end of file\n");
}
if (ferror(fp))
{
perror("write error\n");
}
}
- 对于大量小数据,考虑批量写入减少I/O操作
- 适当设置缓冲区大小可以提高性能
- 频繁的小数据写入可能影响性能,建议积累一定量后一次性写入
常见问题
结构体成员值不正确
原因:可能是结构体填充对齐问题
解决:使用 #pragma pack
或编译器选项控制结构体对齐方式
#pragma pack(push, 1) // 1字节对齐
typedef struct {
// 结构体成员
} MyStruct;
#pragma pack(pop)