三个函数的返回值类型和含义完全不同,这是使用时最容易混淆的地方。下面详细说明:
📌 返回值对比总结
| 函数 | 返回值类型 | 成功时返回值 | 失败/结束时返回值 | 主要用途 |
|---|---|---|---|---|
fgetc() |
int |
读取的字符(0~255) | EOF(通常是 -1) |
判断是否读到文件末尾 |
fgets() |
char* |
指向缓冲区的指针(即传入的 str) |
NULL |
判断是否读取成功 |
fread() |
size_t |
成功读取的元素个数 | 小于请求的元素个数(包括0) | 判断实际读取了多少数据 |
1. fgetc() ------ 返回 字符值 或 EOF
int fgetc(FILE *stream);
- ✅ 成功 :返回读取的字符(转换为
unsigned char再转为int)- 范围:0 ~ 255(ASCII字符)
- ❌ 失败/EOF :返回
EOF(通常是 -1)
正确用法:
int ch; // 必须用 int,不能用 char!
while ((ch = fgetc(fp)) != EOF) {
putchar(ch); // ch 是实际字符
}
⚠️ 重要 :必须用
int类型接收,因为char可能无法区分EOF(-1)和字符0xFF
或者
int ch; // 必须用 int,不能用 char!
while ((ch = fgetc(fp)) != -1) {
putchar(ch); // ch 是实际字符
}
2. fgets() ------ 返回 指针 或 NULL
char *fgets(char *str, int size, FILE *stream);
- ✅ 成功 :返回传入的缓冲区指针(即
str) - ❌ 失败/EOF :返回
NULL
正确用法:
char buf[100];
while (fgets(buf, sizeof(buf), fp) != NULL) {
printf("%s", buf); // buf 包含读取的内容
}
💡 即使只读到一个换行符
\n,也算成功,返回非NULL
3. fread() ------ 返回 元素个数(不是字节数!)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- ✅ 完全成功 :返回
nmemb(请求的元素个数) - ⚠️ 部分成功/EOF :返回实际读取的元素个数 (0 到
nmemb-1) - ❌ 完全失败:返回 0
正确用法:
int arr[10];
size_t count = fread(arr, sizeof(int), 10, fp);
if (count == 10) {
printf("完整读取10个整数\n");
} else if (count > 0) {
printf("部分读取,只读了 %zu 个整数\n", count);
} else {
printf("读取失败或文件为空\n");
}
🔑 关键点 :返回的是元素个数 ,不是字节数!
例如:
fread(buf, 4, 5, fp)最多返回 5(表示5个4字节的元素)
🧪 实际例子对比
假设文件内容:"ABC"(3字节)
// fgetc()
int ch;
while ((ch = fgetc(fp)) != EOF) { // 循环3次,ch分别是 'A','B','C'
// 处理字符
}
// fgets()
char buf[10];
if (fgets(buf, 10, fp) != NULL) { // 返回 buf 的地址(非NULL)
// buf = "ABC\0"
}
// fread()
char data[10];
size_t n = fread(data, 1, 10, fp); // 返回 3(读取了3个1字节的元素)
✅ 使用要点总结
fgetc():用int接收,与EOF比较fgets():与NULL比较,成功时直接使用缓冲区fread():检查返回的元素个数,判断是否完整读取
理解这三个函数返回值的区别,是正确使用它们的关键!