【嵌入式常用函数 1 -- sprintf/snprintf 将变量转化为字符串】

1.1 sprintf 使用介绍

在 C 语言中,可以使用 sprintf 函数将整数类型的变量转换为字符串类型。
以下是一个示例代码:

#include <stdio.h>

int main(void) 
{ 
	int num = 123; 
	char str[20]; 

	sprintf(str, "%d", num); 
	printf("转换后的字符串为: %s\n", str);

	return 0;
 }

在这个例子中,我们使用 sprintf 函数将整数变量 num 转换为字符串类型,并将其存储在字符数组 str 中。
请注意,我们需要提供一个格式化字符串 “%d” 作为第二个参数,以告诉 sprintf 函数我们要将整数类型转换为字符串类型。

1.2 snprintf 使用介绍

snprintf 是一个C语言库函数,用于格式化字符串输出。它可以将不同类型的数据转换成字符串,并按照指定的格式输出到缓冲区中。snprintf 函数的参数包括输出缓冲区、缓冲区大小、输出格式和要转换的数据等。使用snprintf函数可以方便地将数据转换成字符串并输出到屏幕或文件中,常用于调试和日志记录等场景。请注意,使用snprintf函数时应该注意缓冲区大小,避免缓冲区溢出导致程序崩溃。

下面是一个使用snprintf函数的例子:

#include <stdio.h>

int main(void) 
{ 
	char str[50]; 
	int num = 123;
	
	snprintf(str, 50, "The number is %d", num); printf("%s\n", str);

	return 0; 
} 

输出结果为:

The number is 123

在这个例子中,我们将整数类型的变量 num 转换成字符串,并按照指定的格式输出到缓冲区 str 中。使用 printf 函数将缓冲区中的字符串输出到屏幕上。

1.3 sprintf 和 snprintf 的区别

sprintf 和 snprintf 都是 C 语言中的字符串格式化函数,它们的作用都是将字符串格式化后输出到指定的缓冲区中。

不同之处在于,sprintf 函数没有参数限制,它会一直写入数据直到遇到字符串结束符 '\0' 或者缓冲区溢出。这种写入方式可能会导致缓冲区溢出的问题,从而导致程序崩溃或者安全漏洞。

而 snprintf 函数则可以限制写入的最大字符数,防止缓冲区溢出,保证程序的安全性。因此,在实际开发中,建议使用 snprintf 函数来代替 sprintf 函数。

1.4 vsprintf 函数使用介绍

vsprintf 函数是 C 语言中的字符串格式化函数,其作用与 sprintf 函数类似,都是将字符串格式化后输出到指定的缓冲区中。vsprintf 函数可以接受一个 va_list 类型的参数,可以方便地将参数传递给函数内部,而不需要像 sprintf 一样一个一个传递。其函数原型如下:

int vsprintf(char *str, const char *format, va_list ap);

其中,str 是指向缓冲区的指针,format 是格式化字符串,ap 是一个 va_list 类型的参数列表。
使用 vsprintf 函数的步骤如下:

  • 定义一个缓冲区,用于存储格式化后的字符串。
  • 定义一个 va_list 类型的参数列表,用于存储传递给函数的参数。
  • 调用 vsprintf 函数,将格式化后的字符串输出到缓冲区中。
  • 使用缓冲区中的字符串进行后续的操作。

需要注意的是,vsprintf 函数可能会存在缓冲区溢出的问题,因此在使用时需要保证缓冲区的大小足够大,或者使用 snprintf 函数来代替 vsprintf 函数,以保证程序的安全性。

下面是使用 vsprintf 将整数变量字符格式输出的实例:

使用 sprintf 函数将整数变量转换为字符格式输出,然后再使用 vsprintf 函数将字符格式输出转换为可变参数。示例

如下:

#include <stdio.h>
#include <stdarg.h>

void my_printf(const char *format, ...) 
{
	char buffer[1024]; 
	va_list args;
 	
 	va_start(args, format); 
 	vsprintf(buffer, format, args); 
 	va_end(args); 
 	
 	printf("%s", buffer);
  }

int main(void) 
{ 
	int num = 123; 
	char str[32]; 
	
	sprintf(str, "%d", num); 
	my_printf("the number is %s\n", str); 
	
	return 0; 
}

上述代码中,先使用 sprintf 函数将整数变量 num 转换为字符格式输出,然后将其作为参数传递给 my_printf 函数。在 my_printf 函数中,使用 vsprintf 函数将可变参数转换为字符格式输出,然后再输出到标准输出流中。在 main 函数中,调用 my_printf 函数输出 “the number is 123”。

1.5 va_list 定义

在 C 语言中,va_list 是一个指向可变参数列表的指针类型,定义在 stdarg.h 头文件中。其定义如下:

typedef char* va_list;

其中,va_list 实际上是一个指向 char 类型的指针,用来遍历可变参数列表。在使用 va_list 类型的参数列表时,需要使用 va_start、va_arg 和 va_end 函数来访问可变参数。具体用法可以参考前面的示例代码。

1.6 va_start 定义

在 C 语言中,va_start 是一个宏定义,用于初始化可变参数列表的访问。其定义如下:

#define va_start(ap, last) ((void)(ap = (va_list)&(last) + __va_rounded_size(last)))

其中,ap 是一个 va_list 类型的指针,指向可变参数列表的起始位置,last 是最后一个固定参数的名称。__va_rounded_size(last) 是一个宏定义,用于计算 last 参数之后的第一个可变参数的地址,具体实现可以参考 stdarg.h 头文件中的定义。

在使用 va_start 宏时,需要将 ap 和 last 作为参数传递给宏。宏会根据 last 参数的类型和大小来计算可变参数列表的起始位置,并将 ap 指向该位置。使用 va_start 宏后,就可以使用 va_arg 函数来访问可变参数列表中的每一个参数了。

1.6.1 __va_rounded_size 定义

__va_rounded_size(last) 是一个宏定义,用于计算最后一个固定参数之后的第一个可变参数的地址。其定义如下:

#define __va_rounded_size(TYPE) (((sizeof(TYPE) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))

其中,TYPE 是最后一个固定参数的类型。该宏会将 TYPE 的大小向上取整到 int 类型的倍数,并返回取整后的大小。这是因为可变参数列表中的每一个参数都是按照 int 类型的大小进行传递的,所以需要将每个参数的大小向上取整到 int 类型的倍数。这样才能保证可变参数列表中的每一个参数都能够正确地被访问和读取。

1.7 va_end 定义

在 C 语言中,va_end 是一个宏定义,用于结束对可变参数列表的访问。其定义如下:

#define va_end(ap) ((void)(ap = 0))

其中,ap 是一个 va_list 类型的指针,指向可变参数列表的当前位置。使用 va_end 宏后,就可以结束对可变参数列表的访问了。在结束访问前,需要确保已经访问完了所有的可变参数,否则可能会导致未定义的行为。

参考工具:ChatGPT

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

主公CodingCos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值