当我们在写程序的时候,如果传入的参数是确定的,那么依次处理就行;如果参数的长度不确定,该怎么处理呢?
在C中,当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表。如 void func (...)
另外C语言提供了一套标准的处理方法。
先来看看下面的例子。(该函数实现的是:将不定长度的字符输出)
#include "stdarg.h"
void Dug_Printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
}
来一步步分析下每段代码的含义:
(1)首先定义一个va_list型的变量,这个变量是指向参数的指针,也就是指向参数列表里的"...";VA_LIST 是在C语言中解决变参问题的一组宏。
(2)va_start(args, fmt); 和va_end(args); 是一组;前者对定义的参数 进行初始化,让它指向可变参数表里面的第一个参数;后者在获取所有的参数之后,将定义的参数指针关掉,以免发生危险。
(3)vprintf 的作用是将可变参数列表的格式化数据打印到stdout。
(4)fflush(stdout):清空输出缓冲区,并把缓冲区内容输出。
1. int printf(const char *format, ...);
函数返回值为整型。若成功则返回输出的字符数,输出出错则返回负值。
printf()函数的调用格式为:
printf("<格式化字符串>", <参量表>);
其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另一部分是格式化规定字符, 以"%"开始, 后跟一个或几个规定字符,用来确定输出内容格式。
通常我们会将它重定义到串口,用于打印调试信息或者输出关键信息。
如下是stm32上串口使用printf的示例
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)
{
}
return ch;
}
除了上面的printf,我发现在工作中最常用到的就是处理字符串的sprintf和sscanf
2. int sprintf(char *buffer, const char *format, [argument]…)
作用是将格式化的数据写入字符串。
参数:
(1)buffer:是char类型的指针,指向写入的字符串指针;
(2)format:格式化字符串,即在程序中想要的格式;
(3)argument:可选参数,可以为任意类型的数据;
函数返回值:buffer指向的字符串的长度。
如下:
#include
int main()
{
char buffer[10];
char *a = “1234”;
char *b = “abcd”;
sprintf(buffer, ”%s%s”, a, b);
printf(”buffer=%s\n”, buffer);
return 0;
}
输出结果:buffer =1234abcd
3. int sscanf(const char *str, const char *format,......);
作用是:从一个字符串中读进于指定格式相符的数据。利用它可以从字符串中取出整数、浮点数和字符串。
str: 存储的数据
format: 窗体控件字符串。
sscanf有很多应用的场景:
//读取时间
#include
#include
int main()
{
int year, month, day, hour, minute, second;
sscanf("2019-12-12 11:50:24","%d-%d-%d %d:%d:%d",&year, &month, &day, &hour, &minute, &second);
printf("time=%d-%d-%d %d:%d:%d\n", year, month, day, hour, minute, second);
return 0;
}
//取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
sscanf("123456","%4s",str);
printf("str=%s",str);
结果: 1234
sscanf还可以匹配简单的正则表达式提取数据。
//取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
sscanf("1111111abcdedfBCDEF","%[^A-Z]",str);
printf("str=%s",str);
结果: str=1111111abcdedf
其中:% [^A-Z]表示一读入A-Z中的字符就结束读入;那么scanf("%*[^A-Z]")表示一读取到非A-Z的字符就结束读入。
关于字符串的读取和写入就先写这么多,以后遇到不熟悉的继续添加。