fprintf 和 fscanf 是 printf/scanf 的文件版本,功能相同但輸出/輸入目標為磁盤文件而非屏幕/鍵盤。生成的文件可讀性強,適合配置文件、日誌、數據交換。
int fprintf(FILE *fp, const char *format, ...); int fscanf(FILE *fp, const char *format, ...);
fp:文件指針format:格式控制字符串(與 printf/scanf 完全一致)fprintf 返回寫入字符數,失敗返回負數;fscanf 返回成功賦值的參數個數,EOF 表示讀取失敗#include <stdio.h>
#define N 2
struct Student {
char name[10];
int num;
int age;
float score;
};
int main() {
struct Student writeStu[N], readStu[N];
FILE *fp;
int i;
// 以文本讀寫方式打開
if ((fp = fopen("D:\\demo.txt", "wt+")) == NULL) {
printf("Cannot open file!\n");
return 1;
}
printf("請輸入 %d 位學生信息(姓名 學號 年齡 成績):\n", N);
for (i = 0; i < N; i++) {
scanf("%s %d %d %f", writeStu[i].name, &writeStu[i].num,
&writeStu[i].age, &writeStu[i].score);
}
// 寫入文件(每行一條記錄,換行分隔)
for (i = 0; i < N; i++) {
fprintf(fp, "%s %d %d %f\n", writeStu[i].name, writeStu[i].num,
writeStu[i].age, writeStu[i].score);
}
// 重置文件指針到開頭
rewind(fp);
// 從文件讀取
for (i = 0; i < N; i++) {
fscanf(fp, "%s %d %d %f\n", readStu[i].name, &readStu[i].num,
&readStu[i].age, &readStu[i].score);
}
// 顯示讀取結果
printf("\n從文件讀取的數據:\n");
for (i = 0; i < N; i++) {
printf("%s %d %d %.2f\n", readStu[i].name, readStu[i].num,
readStu[i].age, readStu[i].score);
}
fclose(fp);
return 0;
}
請輸入 2 位學生信息: Tom 2 15 90.5 Hua 1 14 99 從文件讀取的數據: Tom 2 15 90.50 Hua 1 14 99.00
Tom 2 15 90.500000 Hua 1 14 99.000000
stdin(標準輸入)、stdout(標準輸出)、stderr(標準錯誤)本質上也是 FILE*,可直接用於 fscanf/fprintf:
#include <stdio.h>
int main() {
int a, b, sum;
fprintf(stdout, "請輸入兩個整數:");
fscanf(stdin, "%d %d", &a, &b);
sum = a + b;
fprintf(stdout, "和 = %d\n", sum);
return 0;
}
此程序行為與 printf/scanf 完全一致,但展示了統一 IO 模型的靈活性。
| 特性 | fprintf/fscanf | fwrite/fread |
|---|---|---|
| 文件格式 | 文本(可讀、可手動編輯) | 二進制(緊湊、不可直接閱讀) |
| 跨平台性 | 好(文本標準) | 需注意字節序、對齊 |
| 性能 | 較慢(格式轉換開銷) | 快(直接內存拷貝) |
| 適用場景 | 配置、日誌、數據交換、調試 | 高性能存儲、大數據量、內部數據 |
fscanf 遇空格/換行視為分隔符,讀取字符串時同 scanf 不含空格fgets 或格式化掃描集 %[^\n]%.2f