//只节选部分代码说明char txt[32];unsigned int Distance=0;while(1) {if(timecount>=50) //500ms采集一次距离{if(CheckChanel[0]==1) {Distance = Read_Distance();if(Distance<1000){Gui_DrawFont_GBK16(100,25,BLUE,GRAY0,"");}sprintf(txt, "%d", Distance);Gui_DrawFont_GBK16(85,25,BLUE,GRAY0,txt); //前两个参数是坐标,显示内容颜色,背景色,数据}timecount=0;LED1=~LED1;}}}
最近项目用到了sprintf函数调试程序,故想写下一篇博客来分析下sprintf函数,其函数原型为:
function prototype
int sprintf(char *buffer ,const char *format, [argument]…);
看到const和指针的声明,我想简单提下几种声明的区别,在经典书《C专家编程》有对恐怖的C语言声明做过解释
/*第1,2种情况,指针所指向的对象是只读的当然对象和指针有可能都是只读的*/const char *format; char const *format;char * const format; //第3种情况指针是只读的/*下面两种方式的声明都能做到这一点-->对象和指针都是只读的*/const char * const format; char const * const format;
小技巧——>Keil5中鼠标放在调用函数名处不动,即可显示出该函数的函数原型
玩透sprintf和printf函数
sprintf是一个变参函数,和printf的功能差不多,只是第一个参数是指定把输出的内容输出到“什么地方”
//网友的例子例:将”test 1 2”写入数组s中#includeint main(int argc, char *avgv[]){char s[40];/*第一个参数就是指向要写入的那个字符串的指针,剩下的就和printf()一样了*/sprintf(s,"%s%d%c","test",1,'2');/*你可以比较一下,这是向屏幕输入*/printf("%s%d%c","test",1,'2');return 0;}
网上找的例子是在标准C语言在PC端调试,最常用的printf打印函数,会直接打印到PC端命令行窗口上,而在单片机调试中,我们常用printf打印有用信息来调试我们的程序,但是却不能直接使用,究其原因,在于标准C语言printf函数的底层实现的机制,已经规定输出流输出到PC端的显示器(或者是现编译器的命令行窗口)。
这也是单片机调试时,为什么要对printf函数进行重定向的原因,所谓重定向,这里涉及流的概念,即“重新定义信息流的流动方向‘’——我从哪里来,又要到哪里去”。即要实现在串口或者LCD上显示,必须重定义标准库函数里面调用的输出设备定义的相关函数。
扩展一下:在C++中,包含了标准库#include ,其中stream英文表示流的意思,iostream库是istream(输入流)和ostream(输出流)组合而成,术语流极其想表达出字符随着时间顺序生成和消失的特点。
#includeint main(){std::cout<<"hello,world";return 0;}
接下来,我们又回到sprintf函数,sprintf在参数列表中多了一个“具体输出到什么地方”的参数。与printf函数不同在于转化后的结果没有送往标准输出设备,而是存放在由指针变量buffer指定的字符缓冲区,这个缓冲区可以是个字符数组。
例如,将浮点数3.14转化成长度为4,含2位小数的字符串,存储在字符缓冲区buffer中,代码如下:
sprintf(buffer,"%4.2f",3.14)
项目中sprintf的用法
#include "stdio.h" //为了解除sprintf警告unsigned int Distance=0;char txt[32];/*这个Distance在上文环境中被定义为距离变量,测距传感器采集的距离值存储在此变量内。*/sprintf(txt, "%d", Distance);//将Distance变量内容按照%d格式放在txt数组中,来方便显示
汇总sprintf三大常犯错误:
1.给定的缓冲区溢出,如给的数组的长度太短而导致溢出。
2.和printf搞混,忘记第一个参数。
3.对应的格式化字符串用错,参数可以有很多个。
char s[40];sprintf(s,"%s%d%c","test",1,'2'); /*这里将内容("test",1,'2')按照指定的格式("%s%d%c")输出到这个地方(s)*/
sprintf函数功能强大,可以方便的完成各类数据类型的转换,但会占用相当大的代码空间。