fprintf宏
最近在调试程序,使用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宏的更多相关文章
- iOS之常用宏定义
下面我为大家提供一些常用的宏定义! 将这些宏定义 加入到.pch使用 再也不用 用一次写一次这么长的程序了 //-------------------获取设备大小------------------- ...
- 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字符串包含欲打开的文件路径及文件名,参 ...
- c++宏使用总结【转】
C/C++中宏总结C程序的源代码中可包括各种编译指令,这些指令称为预处理命令.虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境. ANSI标准定义的C语言预处理程序包括下列命令: #de ...
- 可变参数宏__VA_ARGS__和...
__VA_ARGS__ 是一个可变参数的宏(gcc支持).实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点).这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所 ...
- 可变参数宏__VA_ARGS__
在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:#define pr_debug(fmt,arg...) \printk(KERN_DEBUG fmt,##arg) 用可变参数宏(v ...
- 关于标准C语言的预定义宏【转】
标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义.下面预定义宏表,被我抄了下来. __LINE__ 当 ...
- C语言宏定义时#(井号)和##(双井号)的用法
C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...
- iOS中常见的一些宏
原文链接 1.处理NSLog事件(开发者模式打印,发布者模式不打印) #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr,"%s:% ...
- iOS - 常用的宏定义
1.处理NSLog事件(开发者模式打印,发布者模式不打印) 1 2 3 4 5 #ifdef DEBUG #define NSLog(FORMAT, ...) fprintf(stderr,& ...
随机推荐
- mysql-5.7 密码过期详解
一.起源: 今天一上班就听到说error-log里记录了大量的 ERROR 1820 (HY000): You must reset your password using ALTER USER st ...
- Java:集合,对列表(List)中的数据(整型、字符串、日期等)进行排序(正序、倒序)的方法;字符串按照整型排序的方法
1. 要求 对List列表中的数据进行排序(正序.倒序),列表中的数据包括:整型(Integer).字符串(String).日期(Date)等.对于字符串,要求允许对它按照整型进行排序. 2. 实现思 ...
- adobe acrobat 无效批注对象
http://blog.csdn.net/pipisorry/article/details/40894881 adobe acrobat一直弹出 无效批注对象 检查后提示:"本页面上的全部 ...
- [na]802.1x协议无线认证协议&dot1x有线认证实验
以前搞无线时候,会涉及到无线client接入方式的认证协议. 认证方式+加密方式+有线的dot1x. 注:以前都是doc粘贴到博客的,加上没写博客的习惯,因此会比较乱. EAP(扩展认证协议)是什么? ...
- 递增和递减进度条CCProgressTimer
关于scheduleUpdate看这篇即可 http://www.benmutou.com/blog/archives/56 接下来是示例代码: CCSize size = CCDirector::s ...
- 每日英语:Some Chinese Students Stay Home to Get Ahead
Li Shan's oldest son was the perfect candidate to join the throngs of Chinese students studying abro ...
- ny17 单调递增最长子序列
单调递增最长子序列时间限制:3000 ms | 内存限制:65535 KB难度:4 描述 求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4 输入 ...
- Oracle PLSQL Demo - 09.Open、Fetch遍历游标[Open, Fetch, Close Record CURSOR]
declare r_emp scott.emp%rowtype; cursor cur_emp is select t.* from scott.emp t; begin open cur_emp; ...
- centos7 nginx安装 及MySQL-python
1.pip install MySQL-python 出错问题 pip install -r requirement.txt 发现安装MySQL-python 出错,更新setuptools也没用 解 ...
- python——内置函数和lambda匿名函数
内置函数 接下来,我们就一起来看看python里的内置函数.截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.这 ...