c语言打印程序行号日期方便调试程序(代码片段)

DS小龙哥 DS小龙哥     2023-03-15     725

关键词:

一、前言

平时开发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 DEBUG
static 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;

#else
static 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 DEBUG
static 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;

#else
static 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卡上。

通过编写c语言程序,运行时实现打印另一个程序的源代码和行号

2017年6月1日程序编写说明:1.实现行号的打印,实现代码的读取和输出,理解主函数中的参数含义。2.对fgets函数理解不够3.对return(1);return0的含义理解不够4.未实现页码的打印1/**********************************************************************... 查看详情

c语言第一个c语言小程序——日期算法和万年历2(代码片段)

1.上一篇我们只完成了  a.算出某年某月某日是星期几  b.打印出某年某月的日历这一次我写了一个打印某一年的日历。一开始我是不打算写的,因为可以调用之前的方法,分别打印出这一年12个月的日历。但是这样特别难看... 查看详情

使用gnu/gdb调试linuxc/c++可执行程序查看出错源代码、设置断点

...调试工具,比图形化的调试工具更强大,主要来调试C/C++语言程序。Debug版本的可执行程序包含调试信息,用于程序员调试程序。Release版本的可执行程序往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以... 查看详情

c语言概述(代码片段)

目录一、简单的C程序示例二、示例解释2.1 第1遍:快速概要2.2 第2遍:程序细节三、简单程序的结构五、进一步使用C5.1 程序说明5.2 多条声明5.3 乘法5.4 打印多个值六、多个函数七、调试程序7.1 语法错误7.2 语义错误7.... 查看详情

我的android进阶之旅ndk开发之在c++代码中使用androidlog打印日志,打印内容带有文件文件名方法名行号等信息,方便定位日志输出的地方(代码片段)

一、需求描述1.1原生接口的现状一般,我们在JNI层输出AndroidLog时,直接使用原生的接口,打印如下://实现C语言中打印log到android控制台//导入头文件android/log.h#include<android/log.h>//定义一些宏#defineDEBUG 查看详情

我的android进阶之旅ndk开发之在c++代码中使用androidlog打印日志,打印内容带有文件文件名方法名行号等信息,方便定位日志输出的地方(代码片段)

一、需求描述1.1原生接口的现状一般,我们在JNI层输出AndroidLog时,直接使用原生的接口,打印如下://实现C语言中打印log到android控制台//导入头文件android/log.h#include<android/log.h>//定义一些宏#defineDEBUG 查看详情

调试c/c++程序的常见方法(代码片段)

...入调试运行程序设置断点下一步继续执行设置主函数参数打印变量退出coredump程序日志参考资料gdb调试安装gdb使用前需要安装gdb:yuminstall-ygdb使用前的准备在编译文件时,需要加入参数-g来确保编译后的文件可以被调试。g... 查看详情

调试c/c++程序的常见方法(代码片段)

...入调试运行程序设置断点下一步继续执行设置主函数参数打印变量退出coredump程序日志参考资料gdb调试安装gdb使用前需要安装gdb:yuminstall-ygdb使用前的准备在编译文件时,需要加入参数-g来确保编译后的文件可以被调试。g... 查看详情

c语言进阶学习笔记七程序执行+调试技巧(实用技巧篇)(代码片段)

文章目录一、程序执行篇①预处理详解②宏定义③define标识符字符串④define宏名(参数表)字符串⑤宏和函数对比二、调试技巧篇①什么是bug?②调试是什么?有多重要?③debug和release的介绍④windows环境调试介绍⑥如何写出... 查看详情

程序调试

学编程这么久,调试一直不入门!【C语言调试】【标准c语言调试技巧,打印调试信息技巧】【程序是调试出来的吗?】 查看详情

使用delve调试go应用程序(代码片段)

需要调试器任何编程语言中最简单的调试形式是使用打印语句/日志并写入标准输出。这肯定可以工作,但是当我们的应用程序规模增加并且逻辑变得更加复杂时,它变得极其困难。将打印语句添加到应用程序的每个代码路径都... 查看详情

[c语言]函数与调试

函数与调试        正常程序的调试使用gdb。但有时也会在程序中通过使用printf(),打印关键信息进行bug定位及调试。接下来通过实践不断优化改善:1,通过在程序中直接使用printf()函数进行开发调试... 查看详情

c语言第一个c语言小程序——日期算法和万年历(代码片段)

1.写了个万年历的功能练练手。还没有写交互的代码,只是把方法写完了。先给出头部和方法签名#include<stdio.h>#defineDAYS_PER_WEEK7#defineMONTHS12#defineDATE_HEADER"SunMonTuesWedThurFriSat"intget_days(int,int,int);//返回从公元元年算起,某年某月... 查看详情

zznuoj_用c语言编写程序实现1211:日期排序(附完整源码)(代码片段)

题目描述有一些日期,日期格式为“MM/DD/YYYY”。编程将其按日期大小排列。输入输出样例输入15/12/199910/21/200310/22/200302/12/200411/30/200512/31/2005样例输出15/12/199910/21/200310/22/200302/12/200411/30/200512/31/2005完整源码:#include<stdio.h> 查看详情

hitcon-training学习记录(持续更新)(代码片段)

...续执行至下一个断点处q(quit)退出gdb调试设置操作p变量名打印变量值ptype变量名打印变量的类型setvar变量名=value设置变量值所以,这道题:gdbsysmagicb*0x08048720#没有开启PIE,地址固定rset$edx=$eax#关键:在动调中改变寄存器中变量的值... 查看详情

linux基础常用开发工具——gdb调试器(代码片段)

...行设置断点info/ib:查看断点信息p[变量/表达式]:打印变量/表达式的值(变量名加上取地址符就可以打印出该变量的地址)setvar[变量名]=[要修改的值]:修改变量的值finish:执行到当前函数结束continue/c&#... 查看详情

c语言怎么调试程序

C语言如果调试编的程序如何加断点什么的那些,,,谁能HELPME~~一、在keil中调试c语言程序1、打开我们的程序,点击菜单栏右侧的start/stopdebug..按钮,进入调试模式,如下图。2、左侧为寄存器窗口,右上方是汇编窗口,我们可以看到... 查看详情

电商小程序实战教程-调试方法(代码片段)

...开控制台一般程序写完之后会自动触发编译,控制台也会打印相关的信息。我们利用控制台来查看我们程序的打印输出。那如何打印呢?一般是用console.log方法。比如我们在低码中将全局变量输出可以看到控制台打印出来了用户... 查看详情