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,& ...
随机推荐
- 在QML应用中实现threading多任务
在这个样例中,我们将介绍怎样在QML应用中使用QML语言提供的threading功能,实现多任务. 很多其它的阅读在:http://doc.qt.io/qt-5/qtquick-threading-e ...
- 关于centos7中使用rpm方式安装mysql5.7版本后无法使用root登录的问题
最近在centos7中通过rpm方式安装了最新版本的mysql-server 5.7 (mysql57-community-release-el7-7.noarch.rpm) ,发现安装成功后无法使用 ...
- C# list介绍
一.LIST概述 所属命名空间:System.Collections.Generic public class List<T> : IList<T>, ICollec ...
- mysql (已解决)Access denied for user 'root'@'localhost' (using password: NO)
找到mysql中的my.ini,在最后一行加入 skip-grant-tables 在“管理工具”-”服务” 中重启mysql 解决问题
- sublim3常用插件安装
1首先需要安装插件管理器Package Control,点击View > Show Console菜单,输入以下代码,按回车运行即可.说明:以下只对st3有效 import urllib.req ...
- Web学习篇之---html基础知识(一)
html基础知识(一) 本篇文章主要介绍HTML头部所包括的信息. 一.下面都是在标签<head>...</head>之间的内容: 1.<title>-</t ...
- [na]icmp重定向
这个东西最多平时翻看书时候yy以下或者gns3模拟一下, 实际中还真不曾遇到,直到今天,帮别人解决一个问题时候,抓icmp包发现这个.....忘记了原理,梳理一下 icmp重定向问题 参考
- win常用
//base.Invoke((MethodInvoker)delegate() //{ // this.Close(); //});
- JVM 发生OOM的四种情况
1.Java堆溢出:heap Java堆内存主要用来存放运行过程中所以的对象,该区域OOM异常一般会有如下错误信息;java.lang.OutofMemoryError:Javaheap space此 ...
- .Net 三层架构开发初步
写在前面的话:在课堂上只是听老师讲过三层架构,知道大概是什么意思,我的理解就是将本来混合着写在一起的代码按功能性的不同分别写在不同的项目中,然后上层项目调用下层项目提供的接口,这样可以使代码的层次更清 ...