【ARM 嵌入式 C 字符串系列 23.3 -- snprintf 函数详细介绍并举例】


请阅读【嵌入式开发学习必备专栏 】


snprintf 函数简介

snprintf 函数是 C 语言中的一个标准库函数,用于将格式化的数据写入字符串。它是 printf 函数族的一部分,与 sprintf 类似,但提供了输出缓冲的大小限制,从而增加了程序的安全性,防止了缓冲区溢出的风险。

PRINTF(3)                                                             Linux Programmer's Manual                                                             PRINTF(3)

NAME
       printf, fprintf, dprintf, sprintf, snprintf, vprintf, vfprintf, vdprintf, vsprintf, vsnprintf - formatted output conversion

SYNOPSIS
       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int dprintf(int fd, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const char *format, ...);

       #include <stdarg.h>

       int vprintf(const char *format, va_list ap);
       int vfprintf(FILE *stream, const char *format, va_list ap);
       int vdprintf(int fd, const char *format, va_list ap);
       int vsprintf(char *str, const char *format, va_list ap);
       int vsnprintf(char *str, size_t size, const char *format, va_list ap);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       snprintf(), vsnprintf():
           _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE ||
               || /* Glibc versions <= 2.19: */ _BSD_SOURCE

       dprintf(), vdprintf():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _GNU_SOURCE

函数原型

int snprintf(char *str, size_t size, const char *format, ...);
  • str: 指向用于存储结果字符串的缓冲区的指针。
  • size: 缓冲区str的大小(包括最后的空终止字符)。
  • format: 格式字符串,控制后续参数如何格式化并写入str
  • ...: 零个或多个要写入str的其他参数,数量和类型由format决定。

返回值

snprintf 函数返回预期的字符串长度,不包括最后的空字符。如果返回值大于或等于size,则表示缓冲区太小,无法容纳全部输出。请注意,即使输出被截断,snprintf 也会保证str是空终止的(只要size大于0)。

示例

以下示例展示了如何使用 snprintf 来安全地格式化字符串,并处理可能的截断。

#include <stdio.h>

int main(void) 
{
    char buffer[50];
    int year = 2023;
    char month[] = "October";
    int day = 1;
    
    // 尝试将日期格式化到缓冲区
    int needed = snprintf(buffer, sizeof(buffer), "Today is %s %d, %d", month, day, year);
    
    // 检查是否有足够的空间
    if (needed >= sizeof(buffer)) {
        printf("Buffer too small, needed %d bytes.\n", needed);
    } else {
        printf("%s\n", buffer);
    }
    return 0;
}

这个例子尝试将一个日期格式化为字符串并存储在缓冲区中。如果缓冲区大小不足以容纳完整的输出,则snprintf会返回所需的字符数(不包括最后的空字符)。这允许我们检测并处理潜在的缓冲区溢出情况。

总结

snprintf是一个非常实用的函数,它通过限制写入缓冲区的字符数来防止缓冲区溢出。在处理格式化字符串时,优先使用snprintf而不是sprintf,以提高程序的安全性。

最近更新

  1. TCP协议是安全的吗?

    2024-04-04 12:50:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-04 12:50:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-04 12:50:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-04 12:50:01       20 阅读

热门阅读

  1. Linux 网络: 网卡速度异常案例(1)

    2024-04-04 12:50:01       13 阅读
  2. 服务器硬件基础知识

    2024-04-04 12:50:01       13 阅读
  3. excel怎么快速去掉多个空行

    2024-04-04 12:50:01       14 阅读
  4. 网络安全包括哪些方面?

    2024-04-04 12:50:01       15 阅读
  5. Linux Shell文件描述符和重定向

    2024-04-04 12:50:01       17 阅读
  6. vue2升级到vue3的一些使用注意事项记录(二)

    2024-04-04 12:50:01       13 阅读
  7. 软件设计原则:里氏替换原则

    2024-04-04 12:50:01       13 阅读
  8. dubbo 统一异常处理

    2024-04-04 12:50:01       13 阅读
  9. react diffing算法及函数柯里化

    2024-04-04 12:50:01       18 阅读
  10. 【技巧】Leetcode 136. 只出现一次的数字【中等】

    2024-04-04 12:50:01       19 阅读
  11. 动态规划 Leetcode 392 判断子序列

    2024-04-04 12:50:01       12 阅读
  12. vue实现axios和事件Bus等父子组件的事件传递实现

    2024-04-04 12:50:01       14 阅读