写点什么

C 语言打印程序行号、日期方便调试程序

作者:DS小龙哥
  • 2022 年 5 月 18 日
  • 本文字数:1719 字

    阅读完需:约 6 分钟

一、前言

平时开发 C 语言程序时,经常需要调试代码,C 语言有一些宏,可以打印出当前的行号、文件名称、日期、时间,对程序的调试起到很大的帮助,可以快速定位问题。特别是开发单片机程序时,使用这些宏打印这些信息或者在 LCD 上显示程序的编译日期、时间,可以知道这个单片机上的固件是什么时候编译。帮助判断版本。


ANSIC标准定义了可供C语言使用的预定义宏:__LINE__ : 在源代码中插入当前源代码行号__FILE__ : 在源代码中插入当前源代码文件名__DATE__ : 在源代码中插入当前编译日期__TIME__ : 在源代码中插入当前编译时间
复制代码


其中标识符__LINE__和__FILE__一般用来调试程序,打印信息,方便定位错误。


标识符__DATE__和__TIME__一般可以用来表示固件的版本,方便了解运行的程序是什么时候的版本。


标识符__LINE__是一个整数,其他的文件名称、日期、时间都是字符串。

二、打印示例

printf("编译日期与时间: %s,%s\n", __DATE__,__TIME__);printf("当前所在行号:%d\r\n", __LINE__);printf("当前源文件名称:%s\r\n", __FILE__);printf("当前固件编译日期:%s\r\n", __DATE__);printf("当前固件编译时间:%s\r\n", __TIME__);
复制代码


三、C 语言封装快捷 Debug

#define DEBUG
#ifdef DEBUGstatic int DebugPrintf(const char *format, ...){ va_list arg_data; int count; va_start(arg_data, format); /* 获取可变参数列表 */ fflush(stdout); /* 强制刷新输出缓冲区 */ count = vfprintf(stderr, format, arg_data); /* 将信息输出到标准出错流设备 */ va_end(arg_data); /* 可变参数列表结束 */ return count;}#elsestatic inline int DebugPrintf(const char *format, ...){
}#endif
复制代码


通过 DEBUG 这个宏来开启是否开启调试信息打印功能,如果程序稳定后,不需要打印调试信息,就可以将 DEBUG 的定义取消掉即可。


完整代码:


#include <stdio.h>#include <time.h>#include <stdlib.h>#include <string.h>#include <windows.h>#include <iostream>  #include <string> 
using namespace std;
//#define DEBUG
#ifdef DEBUGstatic int DebugPrintf(const char *format, ...){ va_list arg_data; int count; va_start(arg_data, format); /* 获取可变参数列表 */ fflush(stdout); /* 强制刷新输出缓冲区 */ count = vfprintf(stderr, format, arg_data); /* 将信息输出到标准出错流设备 */ va_end(arg_data); /* 可变参数列表结束 */ return count;}#elsestatic inline int DebugPrintf(const char *format, ...){ return 0;}#endif

int main(){ DebugPrintf("编译日期与时间: %s,%s\n", __DATE__,__TIME__); DebugPrintf("当前所在行号:%d\r\n", __LINE__); DebugPrintf("当前源文件名称:%s\r\n", __FILE__); DebugPrintf("当前固件编译日期:%s\r\n", __DATE__); DebugPrintf("当前固件编译时间:%s\r\n", __TIME__); return 0;}
复制代码

四、STM32 单片机上封装 printf 函数

/*函数功能: 字符串发送*/void USARTx_StringSend(USART_TypeDef *USARTx,u8 *str){   while(*str!='\0')   {       USARTx->DR=*str++;       while(!(USARTx->SR&1<<7)){}   }}
//printf函数底层函数接口int fputc(int c, FILE* stream){ USART1->DR=c; while(!(USART1->SR&1<<7)){} return c;}
/*函数功能: 格式化打印函数*/char USART1_PRINTF_BUFF[1024];void USART1_Printf(char *fmt,...){ va_list ap; /*1. 初始化形参列表*/ va_start(ap,fmt); /*2. 提取可变形参数据*/ vsprintf(USART1_PRINTF_BUFF,fmt,ap); /*3. 结束,释放空间*/ va_end(ap); /*4. 输出数据到串口1*/ USARTx_StringSend(USART1,(u8*)USART1_PRINTF_BUFF); //USART1_Printf("%d%s",123,454656); //int data=va_arg(ap,int);}
复制代码


USART1_Printf 的用法与 printf 是一样的,通过这个函数就可以实现数据打印到任意地方,包括改成存储到 SD 卡上。

发布于: 2022 年 05 月 18 日阅读数: 31
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
C语言打印程序行号、日期方便调试程序_5月月更_DS小龙哥_InfoQ写作社区