C语言中vsnprintf函数的用法详解

标题【C语言】vsnprintf函数的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 标题【C语言】vsnprintf函数的使用
  • 前言
  • 一、vsnprintf是什么?
  • 二、例子
  • 1.示例1
  • 2.示例2
  • 总结

  • 前言

    `在学习stm32串口打印的时候遇到这个vsnprintf函数

        unsigned char UsartPrintfBuf[296];
    	va_list ap;
    	unsigned char *pStr = UsartPrintfBuf;
    	
    	va_start(ap, fmt);
    	vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);		//vsnprintf()格式化
    	va_end(ap);
    

    一、vsnprintf是什么?

    该函数是一个标准的 C 函数,用于格式化字符串并将生成的字符存储在缓冲区中。它与函数类似,但有一个关键区别:函数不是直接采用可变长度的参数列表,而是采用参数,该参数是已使用宏初始化的参数列表。

    以下是该函数的工作原理:vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), fmt, ap);

    该函数采用四个参数:用于存储结果字符串的字符缓冲区、缓冲区的最大大小、指定如何设置参数格式的格式字符串以及包含参数本身的变量。va_list

    该函数读取格式字符串并处理它找到的任何格式说明符。这些格式说明符告诉函数如何格式化 中的参数。va_list

    当它处理每个格式说明符时,该函数会从使用宏中检索下一个参数。va_list va_arg()

    该函数根据格式说明符设置参数的格式,并将生成的字符写入缓冲区。如果生成的字符串比缓冲区长,则该函数将停止写入字符,并返回缓冲区较大时应写入的字符数

    处理完所有参数并将生成的字符串写入缓冲区后,该函数将返回写入缓冲区的字符数(不包括

    'vsnprintf(va_list变量,您可以在运行时将可变长度的参数列表传递给函数,使其比标准更灵活sprintf()功能。

    二、例子

    1.示例1

    代码如下(示例):

    #include <stdio.h>
    #include <stdarg.h>
    
    int main() {
        char buffer[100];
        int len;
    
        len = vsnprintf(buffer, sizeof(buffer), "The answer is %d", 42);
        printf("Result: %s, length: %d\n", buffer, len);
    
        return 0;
    }
    

    在此示例中,我们首先声明一个’缓冲区buffer大小为 100 字节。然后我们调用 'vsnprintf(vsnprintf()使用三个参数:用于存储结果字符串的缓冲区,缓冲区的最大大小(sizeof(buffer)),和格式字符串其中包括一个单一格式说明符 %d表示整数值。

    我们通过42作为参数格式说明符通过使用vsnprintf()函数的可变长度参数列表。

    最后,我们使用 'printf() 打印生成的字符串及其长度

    当我们运行这个程序时,我们得到以下输出:

    Result: The answer is 42, length: 18
    

    2.示例2

    代码如下(示例):

    #include <stdio.h>
    #include <stdarg.h>
    
    void my_printf(char *str, ...) {
        char buffer[100];
        int len;
        va_list args;
    
        va_start(args, str);
        len = vsnprintf(buffer, sizeof(buffer), str, args);
        va_end(args);
    
        printf("Result: %s, length: %d\n", buffer, len);
    }
    
    int main() {
        my_printf("The answer is %d", 42);
        my_printf("My name is %s and my age is %d", "Alice", 25);
    
        return 0;
    }
    

    在这个例子中,我们定义了一个函数’my_printf(这需要一个格式字符串’strstr和可变数量的参数。在函数内部,我们声明了一个字符缓冲区 buffer大小为 100 字节,我们使用va_start()宏初始化一个 'VAva_list对象 'args’ 。

    然后我们调用 'vsnprintf(使用三个参数:用于存储结果字符串的缓冲区buffer,缓冲区的最大大小(sizeof(buffer)),以及格式字符串str和va_list对象args.这允许我们将可变数量的参数传递给vsnprintf()使用 args对象。

    在调用 va_end()宏来清理’参数args对象。

    最后,在 'main()my_printf()两次不同设置字符串格式和参数列表。这第一次调用格式化整数值 42,以及第二次调用设置字符串格式"Alice"和整数值25.

    当我们运行这个程序时,我们得到以下输出:

    Result: The answer is 42, length: 18
    Result: My name is Alice and my age is 25, length: 32
    

    总结

    vsnprintf函数用于将一组变长参数格式化为一个字符串,并将其存储到一个字符缓冲区buffer中。与sprintf()函数不同的是,vsnprintf()函数使用一个va_list参数,该参数包含要格式化的变长参数列表。这使得vsnprintf()函数更加灵活,可以根据需要在运行时传递变长参数列表,而不需要在编译时指定参数类型和数量。你可以传递4个,5个不同类型的参数,而且不用在函数定义的时候规定参数类型和数量。

    虽然可以传递的参数数量有很多个,但也是有限制的,限制通常是由堆栈的大小或可用内存施加的,而不是由函数本身施加的。vsnprintf()
    该函数接受可变数量的参数,这些参数通过对象传递给它。对象的大小由传递给它的参数的数量和大小决定va_list如果尝试将过多参数传递给vsnprintf() ,则可能会遇到堆栈溢出错误或内存不足。确切的限制将取决于平台和可用资源。

    但是在实践中,很少遇到此限制,因为大多数程序不需要将大量参数传递给vsnprintf() 。如果您发现需要将大量参数传递给vsnprintf() ,则可能需要考虑重构代码以使用更节省内存的其他方法。

    物联沃分享整理
    物联沃-IOTWORD物联网 » C语言中vsnprintf函数的用法详解

    发表评论