《玩透嵌入式C的角角落落》深入分析sprintf和printf函数
Posted 嵌入式历练者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《玩透嵌入式C的角角落落》深入分析sprintf和printf函数相关的知识,希望对你有一定的参考价值。
//只节选部分代码说明
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中 #include<stdio.h> int 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(输出流)组合而成,术语流极其想表达出字符随着时间顺序生成和消失的特点。
#include<iostream>
int 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函数功能强大,可以方便的完成各类数据类型的转换,但会占用相当大的代码空间。
以上是关于《玩透嵌入式C的角角落落》深入分析sprintf和printf函数的主要内容,如果未能解决你的问题,请参考以下文章