在后台程序运行出问题时,详尽的日志是抓错不可缺少的帮手,这里提供一个能自动记录日志触发点文件名、行号、函数名的方法,关键是利用C99新增的预处理标识符__VA_ARGS__

先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息。

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

__DATE__:在源文件中插入当前的编译日期

__TIME__:在源文件中插入当前编译时间;

__STDC__:当要求程序严格遵循ANSI C标准时该标识被赋值为1;

__cplusplus:当编写C++程序时该标识符被定义。

代码:

#define LOG(level, format, ...) /
do { /
fprintf(stderr, "[%s|%s@%s,%d] " format "/n", /
level, __func__, __FILE__, __LINE__, ##__VA_ARGS__ ); /
} while (0) int main()
{
LOG(LOG_DEBUG, "a=%d", 10);
return 0;
}

运行结果:
[DEBUG|main@a.c,17] a=10

  

限制是format不能是变量,必须是常量字符串,如果要记录一个变量字符串,不能像printf那样printf(s)了,要LOG("DEBUG", "%s", s)。

另外还有一种:

//============================================================================
// Name : debug.cpp
// Author : boyce
// Version : 1.0
// Copyright : pku
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h> #define __DEBUG__ #ifdef __DEBUG__
#define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __LINE__, ##__VA_ARGS__)
#else
#define DEBUG(format,...)
#endif int main(int argc, char **argv) {
char str[]="Hello World";
DEBUG("A ha, check me: %s",str);
return 0;
}

  

C++日志之获取函数的名字,行号,文件名的更多相关文章

  1. python中获取当前位置所在的行号和函数名(转)

    http://www.vimer.cn/2010/12/%E5%9C%A8python%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E4%BD%8D%E7 ...

  2. python中获取当前位置所在的行号和函数名(转)

    http://www.vimer.cn/2010/12/%E5%9C%A8python%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E4%BD%8D%E7 ...

  3. ReportingService 通过RowNumber函数获取行号和生成隔行变色样式

    以前一直没有搞明白SSRS里面的RowNumber函数到底该怎么用,所以一直没有很好的办法在SSRS中的表格上实现隔行变色的样式,实现隔行变色的关键就是获取表格中每一行的行号.在最近了解了下这个函数, ...

  4. C#获取堆栈信息,输出文件名、行号、函数名、列号等

    命名空间:System.Diagnostics 得到相关信息: StackTrace st = new StackTrace(new StackFrame(true));StackFrame sf = ...

  5. 模拟log4j获取日志对象调用所在的类名、方法名及行号

    当我们在记录日志时,每个类中会定义一个日志对象,然后利用这个对象去写日志,那么我们在处理日志时,如何能才能记录日志对象所在的类.方法和行号呢?log4j中已经实现了该功能,那么它是怎么实现的呢? 其实 ...

  6. 使用StackTrace堆栈跟踪记录详细日志(可获取行号)

    上一篇我们提到使用.NET自带的TraceSource实现简单的日志,具体请看<轻松背后的N+疲惫——系统日志>,这一篇注意想讲的是日志的详细记录,包含请求开始到结束的过程中调用的方法链以 ...

  7. go包之logrus显示日志文件与行号

    前言: logrus是go中比较好的一个log模块.github上的很多开源项目都在使用这个模块, 我在写这个博文时, github上的logrus的stars数已经有8214了.最近在用这个模块时, ...

  8. linux,shell脚本中获取脚本的名字,使用脚本的名字。

    需求描述: 写shell脚本的过程中,有时会需要获取脚本的名字,比如,有的时候,脚本 中会有usage()这种函数,可能就会用到脚本的名字. 实现方法: shell脚本中,通过使用$0就可以获取到脚本 ...

  9. iOS开发中全量日志的获取

    我们在app中对崩溃.卡顿.内存问题进行监控.一旦监控到问题,我们就需要记录下来,但是,很多问题的定位仅靠问题发生的那一刹那记录的信息是不够的,我们需要记录app的全量日志来获取更多的信息. 一,使用 ...

随机推荐

  1. Lucene的基本应用

    import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; ...

  2. [Servlet&amp;JSP] 从JSP到Servlet

    JSP与Servlet是一体的两面,JSP最后都会被容器转译为Servlet源码,自己主动编译为.class文件,载入.class文件然后生成Servlet对象. 由容器转译后的Servlet类具有_ ...

  3. Java中的BigInteger在ACM中的应用

    Java中的BigInteger在ACM中的应用 在ACM中的做题时,常常会遇见一些大数的问题.这是当我们用C或是C++时就会认为比較麻烦.就想有没有现有的现有的能够直接调用的BigInter,那样就 ...

  4. react 通过 classnames 处理 多个class 的问题

    react原生动态添加多个className会报错: import style from './style.css' <div className={style.class1 style.cla ...

  5. Solaris网络基础

      划分子网: 把大网缩小为若干个小网.修改子网掩码,划分多个网络. 那么如何确定子网的子网掩码和IP地址? 以上你会发现少了6个IP.   Ifconfig e1000g0 down down掉网卡 ...

  6. WPF 基础到企业应用系列1——开篇故意

    參考资料 提到參考资料,大家第一感觉就是MSDN,当然我也不例外.这个站点基本上是学习微软技术的首选站点,除了这个站点以外,我还參考了非常多其它的社区和站点,基本上都在.NET 技术社区之我见(英文篇 ...

  7. Logical Volume Manager (Linux)

    http://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux) Logical Volume Manager (Linux) From Wiki ...

  8. Linux多线程编程的条件变量

    在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...

  9. ajax短信验证码-mvc

    <script type="text/javascript"> function SendMessage() { var phoneNumberInput = docu ...

  10. CCNET自动构建之路

    人永远追求效率(想偷懒),不想手动编译项目.发布站点于是产生了自动构建技术,.NET领域中CCNET是个不错的选择. 一路问题不少,记录一下. 准备环境 服务器上需要有iis.vs(与开发环境的版本一 ...