1. 函数原型
#include <cstdio>
// 或者 #include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);
- 头文件:
<cstdio> (C++)或 <stdio.h> (C)
- 命名空间:若用
<cstdio> ,可以写作 std::fprintf ,也可用全局作用域 ::fprintf 。
2. 参数详解
参数 |
类型 |
含义 |
stream |
FILE * |
目标文件流指针(如 stdout 、stderr 或 fopen 返回值) |
format |
const char * |
格式字符串,包含普通字符和格式说明符 |
... |
可变参数 |
与 format 中说明符对应的数据 |
stream :必须是已成功打开的文件流,否则行为未定义。
format :类似于 printf ,通过 % 引入占位符。
3. 返回值
- ≥0:成功写入字符的总数(不含终止符)。
<0 :出错(例如磁盘满、流被关闭),会设置 errno 。
调用后若想判断是否出错,可:
if (fprintf(fp, "%d\n", x) < 0) {
perror("fprintf failed");
// 进一步错误处理
}
4. 常见格式说明符
说明符 |
类型 |
备注 |
%d |
int |
十进制整数 |
%u |
unsigned int |
无符号十进制整数 |
%ld |
long |
长整型 |
%lld |
long long |
长长整型 |
%f |
double |
浮点数 |
%c |
char |
单个字符 |
%s |
char * |
C 风格字符串(以 '\0' 结尾) |
%p |
void * |
指针地址 |
%% |
— |
输出单个 % 符号 |
5. 示例代码
#include <cstdio>
int main() {
// 打开文件用于写入(不存在时创建)
FILE *fp = std::fopen("output.txt", "w");
if (!fp) {
perror("fopen");
return 1;
}
int a = 42;
double pi = 3.14159;
const char *name = "Alice";
// 向文件写入格式化内容
fprintf(fp, "Name: %s\n", name);
fprintf(fp, "Integer: %d, Hex: 0x%x\n", a, a);
fprintf(fp, "Float: %.2f\n", pi);
std::fclose(fp);
return 0;
}
运行后,output.txt 内容类似:
Name: Alice
Integer: 42, Hex: 0x2a
Float: 3.14
6. 文件打开模式与缓冲
"w" :写入模式,文件存在清空,不存在则创建。
"a" :追加模式,文件尾写入。
"r+" /"w+" /"a+" :读写模式。
默认情况下,输出到磁盘前会缓冲(通常行缓冲或全缓冲)。若需立即写出,可以调用:
fflush(fp);
或者在打开时使用无缓冲/行缓冲设置:
setvbuf(fp, nullptr, _IONBF, 0); // 无缓冲
7. 错误处理
8. 与 C++ 流(std::ofstream /std::cout )的比较
特性 |
fprintf |
C++ 流 (<< ) |
性能 |
较高(无类型安全检查) |
较低(有类型安全、格式化灵活) |
可移植性 |
跨 C/C++ 平台一致 |
某些老平台表现差异 |
类型安全 |
无,易错 |
有,编译期类型检查 |
国际化/本地化 |
需手动设置 setlocale |
内置支持更好 |
9. 注意事项
- 类型匹配:传参类型必须与说明符一致,否则未定义行为。
- 缓冲与多线程:标准 I/O 默认锁定(线程安全),但频繁锁定可能影响性能,可使用
flockfile /funlockfile 批量输出。
- 安全函数:在 MSVC 上可使用
fprintf_s ,多一个参数校验。
- 宽字符:若需输出宽字符,请用
fwprintf 、wchar_t* 、%ls 等。
|