在进行文件操作时,C语言为我们提供了多种强大而灵活的函数。本文将详细介绍常用的文件读写函数:fread、fgets、fgetc、fscanf、fwrite、fputs 和 fputc,并通过示例代码加以说明。
一、文件读取函数(从文件里“读”数据)
1. fread —— 读二进制数据块
函数原型
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
参数解释:
ptr:指向接收数据的缓冲区的指针。size:每个数据块的大小(以字节为单位)。count:要读取多少个数据块。stream:文件指针。
返回值: 成功时返回实际读取的元素个数
代码示例:
#include
int main() {
FILE *fp = fopen("example.bin", "rb"); // 打开一个二进制文件,模式为“读”(r)+“二进制”(b)
if (!fp) return 1; // 打开失败就退出
char buffer[100]; // 创建一个长度为100的字符数组来接收数据
size_t n = fread(buffer, sizeof(char), 100, fp); // 读取最多100个字节到 buffer 中
printf("Read %zu bytes\n", n); // 打印实际读取的字节数
fclose(fp); // 关闭文件
return 0;
}
2. fgets —— 一次读一行,适合文本文件
函数原型:
char *fgets(char *str, int n, FILE *stream);
参数解释:
str:接收读取结果的字符数组。n:最多读取 n-1 个字符,留一个位置给字符串结束符 \0。stream:文件指针。
返回值:成功时返回 str 指针(即读取的字符串),失败(如出错或遇到 EOF 且无数据读入)返回 NULL
代码示例:
#include
int main() {
FILE *fp = fopen("example.txt", "r"); // 打开文本文件,模式为只读
if (!fp) return 1;
char line[256]; // 准备一个数组来存放每一行
while (fgets(line, sizeof(line), fp)) { // 逐行读取文件内容
printf("%s", line); // 打印当前行
}
fclose(fp);
return 0;
}
3. fgetc —— 一次读一个字符
函数原型:
int fgetc(FILE *stream);
返回值:成功时返回读取的字符(作为 unsigned char 转为 int 类型),
若遇到 EOF 或出错,返回 EOF(通常是 -1)。
代码举例:
#include
int main() {
FILE *fp = fopen("example.txt", "r"); // 打开文本文件
if (!fp) return 1;
int ch;
while ((ch = fgetc(fp)) != EOF) { // fgetc 读取一个字符(返回 int),遇到文件结尾返回 EOF
putchar(ch); // 输出读取的字符
}
fclose(fp);
return 0;
}
4. fscanf —— 从文件中格式化读取,类似 scanf
函数原型:
int fscanf(FILE *stream, const char *format, ...);
返回值:成功时返回成功读取并赋值的项目数;若读取失败返回 EOF,即未读取任何值且遇到输入错误或 EOF。
假设 data.txt 中有如下内容:
Tom 25
代码举例:
#include
int main() {
FILE *fp = fopen("data.txt", "r"); // 打开文件
if (!fp) return 1;
char name[50];
int age;
fscanf(fp, "%s %d", name, &age); // 从文件中读取一个字符串和一个整数
printf("Name: %s, Age: %d\n", name, age); // 打印结果
fclose(fp);
return 0;
}
二、文件写入函数(把数据“写”进文件)
1. fwrite —— 写二进制数据块
函数原型
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
返回值:成功时返回实际写入的元素个数
代码举例:
#include
int main() {
FILE *fp = fopen("output.bin", "wb"); // 打开文件写二进制数据(w + b)
if (!fp) return 1;
char data[] = "Hello, binary!";
fwrite(data, sizeof(char), sizeof(data), fp); // 写入整个字符串(包括结尾的 '\0')
fclose(fp);
return 0;
}
2. fputs —— 写一行字符串(不自动加换行)
函数原型:
int fputs(const char *str, FILE *stream);
str:指向要写入的以 null 结尾的字符串(const char *)。stream:表示写入目标的文件流(通常由 fopen() 打开)。
返回值:成功时返回非负数(通常是最后一个写入字符的 ASCII 值)
代码举例:
#include
int main() {
FILE *fp = fopen("output.txt", "w"); // 打开文本文件写入
if (!fp) return 1;
fputs("This is a line.\n", fp); // 写入一行(我们手动加了换行)
fclose(fp);
return 0;
}
3. fputc —— 写一个字符
函数原型:
int fputc(int character, FILE *stream);
character:要写入的字符(注意是 int 类型,但只写入低 8 位)。stream:目标文件指针。
返回值:成功时返回写入的字符(作为 unsigned char 转为 int 类型)
代码举例:
#include
int main() {
FILE *fp = fopen("output.txt", "w"); // 打开文件写入
if (!fp) return 1;
fputc('A', fp); // 写入字符 A
fputc('\n', fp); // 写入换行符
fclose(fp);
return 0;
}
总结:
函数类型作用使用场景fread读取读取二进制数据图片、音频等非文本文件fgets读取读取一行字符串文本文件(逐行读)fgetc读取读取一个字符逐个字符分析文件fscanf读取按格式读取文本数据(如姓名、数字)fwrite写入写入二进制数据保存图片、日志fputs写入写入字符串写入一行或多行文本fputc写入写入一个字符控制字符写入(逐个字符)