最近在调试程序,使用printf函数和调试信息都不能在终端输出,所以使用比较笨的方法。将调试信息写到文件中,再查看文件。由于要多次使用fprintf函数,所以将其写成宏。

参考链接:

http://www.cnblogs.com/alexshi/archive/2012/03/09/2388453.html

“…”表示零个或多个参数,后面使用__VA_ARGS__把参数传递给宏。当宏的调用展开时,实际的参数就传递给 fprintf()了。

将宏定义成一个函数,这样一来每次都会执行一次完成的操作,当在同一个函数内部多次使用同一个宏的时候,其中函数定义的局部变量不会和其他的函数冲突,如果不定义成函数的话,编译器就会报错。

debug.h

 #ifndef _DEBUG_H_
#define _DEBUG_H_ #define DEBUG(info,...) \
{ \
FILE *fp; \
fp = fopen("log", "a+");\
fprintf(fp, "%d,%s", \
__LINE__, __func__);\
fprintf(fp,info, __VA_ARGS__);\
fclose(fp); \
} #endif

debug.c

 #include <stdio.h>
#include "debug.h" int main()
{
DEBUG("hello\n");
return ;
}

编译

gcc debug.c

出现如下问题

而将main函数中更改,增加一个参数。改为DEBUG("hello\n",123);

再次编译,编译通过,运行程序,查看生成的文件,已经将内容写到里面。

上网查阅,解决问题方法1,可变参数前面加上“##”,如果可变参数为空,那么“##”可以使编译器去掉前面的空格。

 #ifndef _DEBUG_H_
#define _DEBUG_H_ #define DEBUG(info,...) \
{ \
FILE *fp; \
fp = fopen("log", "a+");\
fprintf(fp, "%d,%s", \
__LINE__, __func__);\
fprintf(fp,info, ## __VA_ARGS__);\
fclose(fp); \
} #endif

当可变参为零,DEBUG("hello\n");编译通过。

解决方法2,更改宏如下所示,再次只打印一个字符串就,不会有问题。

 #ifndef _DEBUG_H_
#define _DEBUG_H_ #define DEBUG(...) \
{ \
FILE *fp; \
fp = fopen("log", "a+");\
fprintf(fp, "%d,%s", \
__LINE__, __func__);\
fprintf(fp,__VA_ARGS__);\
fclose(fp); \
} #endif

DEBUG("hello\n");编译通过,

但是当可变参为零,即

DEBUG();

出现如下错误

fprintf宏的更多相关文章

  1. iOS之常用宏定义

    下面我为大家提供一些常用的宏定义! 将这些宏定义 加入到.pch使用 再也不用 用一次写一次这么长的程序了 //-------------------获取设备大小------------------- ...

  2. Linux C 文件输入输出函数 fopen()、getc()/fgetc()、putc()/fputc()、fclose()、fprintf()、fscanf()、fgets()、fputs()、fseek()、ftell()、fgetpos()、fsetpos() 详解

      fopen(打开文件) 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参 ...

  3. c++宏使用总结【转】

    C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境. ANSI标准定义的C语言预处理程序包括下列命令:  #de ...

  4. 可变参数宏__VA_ARGS__和...

    __VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...

  5. 可变参数宏__VA_ARGS__

    在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...

  6. 关于标准C语言的预定义宏【转】

    标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__  当 ...

  7. C语言宏定义时#(井号)和##(双井号)的用法

    C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...

  8. iOS中常见的一些宏

    原文链接 1.处理NSLog事件(开发者模式打印,发布者模式不打印) #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr,"%s:% ...

  9. iOS - 常用的宏定义

    1.处理NSLog事件(开发者模式打印,发布者模式不打印) 1 2 3 4 5   #ifdef DEBUG   #define NSLog(FORMAT, ...) fprintf(stderr,& ...

随机推荐

  1. JavaScript - 返回头部

    制作浮动top $(window).scroll( function() { var scrollValue=$(window).scrollTop(); scrollValue > 600 ? ...

  2. 笔记本上安装centos7

    1.下载centos的dvd镜像就够了.地址: 2.制作u盘镜像. 1)下载安装UltraIOS,(百度云->软件文件夹有,for me). 2)打开镜像,选择“启动”-->“写入硬盘镜像 ...

  3. Disable Oracle Automatic Jobs

    By default, Oracle will run some maintance jobs every night. If you don't want to run those jobs, yo ...

  4. python3.3使用tkinter实现猜数字游戏代码

    发布时间:2014-06-18   编辑:www.jbxue.com 原文地址:http://www.jbxue.com/article/python/22152.html python3.3使用tk ...

  5. C#修改GIF大小同时保持GIF仍然可动和背景透明

    /// <summary> /// 设置GIF大小 /// </summary> /// <param name="path">图片路径< ...

  6. python学习之itsdangerous模块

    类 from itsdangerous import URLSafeTimedSerializer as ustsr class ustsr(secret_key) 参数: secret_key可以是 ...

  7. python super()使用详解

    1.super的作用调用父类方法2.单继承使用示例 #coding:utf-8 #单继承 class A(object): def __init__(self): self.n=2 def add(s ...

  8. hdoj1160 FatMouse's Speed 动态规划

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. [转]好用工具:Oracle SQL Developer

    我們一直以來就很少使用 Oracle 資料庫,一年下來也頂多 1 ~ 2 個案子採用 Oracle 的資料庫,所以一直都對 Oracle 資料庫的操作不太熟悉,尤其是用 Oracle 內建的那些超難用 ...

  10. C++使用ocilib访问oracle数据库

    引用: http://blog.csdn.net/u011311985/article/details/51221898 测试程序我放到 http://download.csdn.NET/detail ...