找回密码
 register

QQ登录

只需一步,快速开始

查看: 5|回复: 1

[C++] C++ fprintf 函数详解

[复制链接]

[C++] C++ fprintf 函数详解

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:240
  • 打卡月天数:17
  • 打卡总奖励:238
  • 最近打卡:2025-07-19 00:57:06
Waylee

主题

0

回帖

2万

积分

仙帝

积分
26258
Waylee 2025-7-19 00:57 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

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 * 目标文件流指针(如 stdoutstderr 或 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. 错误处理

  • 写入失败时 fprintf 返回负值,且 errno 被设置。常见原因:

    • 文件系统只读或磁盘已满
    • 文件流被关闭
  • 可用 perror()strerror(errno) 获取错误信息。

8. 与 C++ 流(std::ofstream/std::cout)的比较

特性 fprintf C++ 流 (<<)
性能 较高(无类型安全检查) 较低(有类型安全、格式化灵活)
可移植性 跨 C/C++ 平台一致 某些老平台表现差异
类型安全 无,易错 有,编译期类型检查
国际化/本地化 需手动设置 setlocale 内置支持更好

9. 注意事项

  1. 类型匹配:传参类型必须与说明符一致,否则未定义行为。
  2. 缓冲与多线程:标准 I/O 默认锁定(线程安全),但频繁锁定可能影响性能,可使用 flockfile/funlockfile 批量输出。
  3. 安全函数:在 MSVC 上可使用 fprintf_s,多一个参数校验。
  4. 宽字符:若需输出宽字符,请用 fwprintfwchar_t*%ls 等。
  • 打卡等级:热心大叔
  • 打卡总天数:240
  • 打卡月天数:17
  • 打卡总奖励:238
  • 最近打卡:2025-07-19 00:57:06
楼主
Waylee 楼主

主题

0

回帖

2万

积分

仙帝

积分
26258
Waylee 2025-7-19 01:08 | 显示全部楼层 | Google Chrome | Windows 10

微软的 Visual C++ 编译器从 VS2005 起,就在标准 C 库里把一批老旧的、潜在“不安全”函数(如 fopen、strcpy、sprintf 等)标记为“已弃用”(deprecated),以鼓励你改用带“_s”后缀的“安全”版本(如 fopen_s、strcpy_s、sprintf_s)。

在Windows下的写法:
#include <cstdio>

int main() {
    // 打开文件用于写入(不存在时创建)
    FILE* fp = nullptr;
    errno_t err = fopen_s(&fp, "output.txt", "w");
    if (err != 0) {
        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;
}

如果想继续用 fopen 而不改代码
在代码里禁用警告
在包含任何头文件之前,加入:

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |网站地图|天天打卡

GMT+8, 2025-7-19 08:38 , Processed in 0.102074 second(s), 6 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表