当前位置: 首页 > article >正文

【C++】避开 C 语言的格式化输出陷阱:掌握 printf、sprintf、snprintf、fprintf、vsprintf

文章目录

  • 理解 `printf`、`sprintf`、`snprintf` 及其家族函数
    • 1. `printf` 函数
      • 语法
      • 示例
    • 2. `sprintf` 函数
      • 语法
      • 示例
    • 3. `snprintf` 函数
      • 语法
      • 示例
    • 4. `fprintf` 函数
      • 语法
      • 示例
    • 5. `vsprintf`、`vsnprintf` 和 `vfprintf` 函数
      • 语法
      • 示例
    • 总结


理解 printfsprintfsnprintf 及其家族函数

在 C 语言编程中,格式化输出函数是非常常用的工具。最常见的函数包括 printfsprintfsnprintffprintf 等。虽然它们的功能类似,但在使用时有一些重要的区别。本文将介绍这些函数的用法及其主要区别。

1. printf 函数

printf 是最基本的格式化输出函数。它用于将格式化的字符串输出到标准输出(通常是屏幕)。

语法

int printf(const char *format, ...);
  • 参数:

    • format:一个格式字符串,其中可以包含文本和格式说明符(如 %d%s 等)。
    • ...:可变参数,根据 format 中的格式说明符提供相应的值。
  • 返回值: 成功时返回输出的字符数,失败时返回负值。

示例

int main() {
    int num = 10;
    printf("Number: %d\n", num);
    return 0;
}

输出:

Number: 10

2. sprintf 函数

sprintf 用于将格式化字符串存储在一个字符数组(字符串)中,而不是输出到控制台。

语法

int sprintf(char *str, const char *format, ...);
  • 参数:

    • str:目标字符数组,用于存储生成的格式化字符串。
    • 其余参数与 printf 类似。
  • 返回值: 成功时返回存入字符串的字符数,失败时返回负值。

示例

int main() {
    char buffer[50];
    int num = 10;
    sprintf(buffer, "Number: %d", num);
    printf("%s\n", buffer);
    return 0;
}

输出:

Number: 10

3. snprintf 函数

snprintfsprintf 的增强版,增加了一个参数来指定存储字符的最大数量,防止缓冲区溢出。

语法

int snprintf(char *str, size_t size, const char *format, ...);
  • 参数:

    • size:指定要写入的最大字符数(包括终止符 \0)。
    • 其余参数与 sprintf 相同。
  • 返回值: 如果格式化后的字符串长度小于 size,返回实际写入字符数;如果格式化后的字符串长度大于或等于 size,返回应写入的字符总数(不包括终止符)。

示例

int main() {
    char buffer[10];
    int num = 12345;
    snprintf(buffer, sizeof(buffer), "Number: %d", num);
    printf("%s\n", buffer);
    return 0;
}

输出:

Number: 12

注意:输出结果为 Number: 12,因为 buffer 的大小限制了完整字符串的写入。

4. fprintf 函数

fprintfprintf 类似,但它允许将格式化输出写入到指定的文件流。

语法

int fprintf(FILE *stream, const char *format, ...);
  • 参数:
    • stream:文件指针,指向目标文件。
    • 其余参数与 printf 相同。

示例

int main() {
    FILE *file = fopen("output.txt", "w");
    if (file == NULL) {
        printf("Failed to open file\n");
        return 1;
    }
    int num = 10;
    fprintf(file, "Number: %d\n", num);
    fclose(file);
    return 0;
}

输出:
该程序会在 output.txt 文件中写入 Number: 10

5. vsprintfvsnprintfvfprintf 函数

这些函数的功能类似于 sprintfsnprintffprintf,但它们接受 va_list 作为参数,这在处理可变参数的函数时特别有用。

语法

int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
  • 参数:
    • apva_list 类型的变量,表示变长参数列表。

示例

#include <stdarg.h>

void myPrintf(const char *format, ...) {
    char buffer[100];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);
    printf("%s", buffer);
}

int main() {
    myPrintf("Number: %d\n", 10);
    return 0;
}

输出:

Number: 10

总结

  • printf:用于标准输出。
  • sprintf:用于将格式化字符串写入字符数组。
  • snprintf:类似于 sprintf,但提供了安全的缓冲区大小控制。
  • fprintf:用于将格式化字符串写入文件。
  • vsprintfvsnprintfvfprintf:用于处理变长参数列表的变体。

理解这些函数的不同用途及其安全性考量是高效、稳健的 C 语言编程的基础。掌握它们,您将在编码过程中更加得心应手。


http://www.kler.cn/news/284534.html

相关文章:

  • 使用 pnpm workspace 和 standalone 模式构建 Next.js 的 Docker 镜像
  • ceph rgw reshard (by quqi99)
  • Ubuntu 24.04 中安装网易邮箱大师
  • JVM下篇:性能监控与调优篇-02-JVM监控及诊断工具-命令行篇
  • mybatisplus + oracle + spring boot遇到的一些问题
  • python基础学习(最终篇)
  • Unclutter - 苹果电脑(Mac)桌面文件笔记剪贴板管理工具
  • jenkins如何生成报告并查看报告,如何安装allure插件
  • MySQL-基础篇-事务(事务简介、事务操作、事务的四大特性、并发事务引发的问题、事务的隔离级别)
  • 前波士顿咨询Platinion董事总经理陈果加入望繁信科技
  • RK3568平台(平台总线篇)SPI驱动框架分析
  • 今日算法:蓝桥杯基础题之“星系炸弹”
  • Python | Leetcode Python题解之第384题打乱数组
  • Claude 与 ChatGPT:哪个更适合学术写作,深入对比分析
  • linux批量解压tar.gz文件
  • I/0系统基本概念
  • ORACLE 统计信息的备份与恢复
  • Servlet 简介+ Cookie和session+过滤器Filter和监听器Listener
  • Vue3 ref 和 reactive 的区别
  • 命名空间using namespace std
  • Python编码系列—Python代码重构:提升代码质量
  • 编成笔记-atan2函数学习分析
  • spring 声明式事务方法自调用问题
  • C与C++的三种区分方式
  • 脚手架工具的应用(前端和后端搭建)
  • 惠中科技光伏清洁领域的专业引领者
  • Android音视频开发,需要学些什么?
  • 排序算法之希尔排序详细解读(附带Java代码解读)
  • TCP 协议详解
  • 同城小程序怎么做 同城小程序系统开发制作方案