在linux編程中,當文件數量變的衆多之後,使用gdb調試就是一場災難。因此在程序中加入合理的打印信息,定位錯誤出現的文件名,函數名,行號等信息,能更高效的定位到問題的所在。
下面定義了宏,分別是WARNING,INFO,ERROR,SHOW_TIME,DEBUG等。利用了 __FILE__,_FUNCTION__, __LINE__等變量。。。
_FILE__,__FUNCTION__, __LINE__ 從名字可以直接看出來了,對應的:代碼文件名,函數名, 行號。
下面就是定義的宏:
- #define ERROR(...) /
- do{ /
- fprintf(stderr, "[ERROR ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
- fprintf(stderr, __VA_ARGS__); /
- }while(0)
- #define WARNING(...) /
- do{ /
- fprintf(stdout, "[WARNING]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
- fprintf(stdout, __VA_ARGS__); /
- }while(0)
- #define INFO(...) /
- do{ /
- fprintf(stdout, "[INFO ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
- fprintf(stdout, __VA_ARGS__); /
- }while(0)
- #define SHOW_TIME(...) /
- do{/
- extern unsigned long long gLatestTime;/
- timeval tp;/
- gettimeofday(&tp, NULL);/
- unsigned long long now = tp.tv_sec*1000000+tp.tv_usec; /
- if(gLatestTime != 0) /
- { /
- fprintf(stdout, ">>>>>>>>>Used Time: %s[%d], %s: %ld.%ld, %llu ms ", __FILE__, __LINE__, __func__, tp.tv_sec, tp.tv_usec, (now-gLatestTime)/1000);/
- fprintf(stdout, __VA_ARGS__); /
- fprintf(stdout, "/n"); /
- } /
- gLatestTime = now;/
- }while(0)
- #ifdef DEBUG
- #define DBG(...) /
- do{ /
- fprintf(stdout, "[DEBUG ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
- fprintf(stdout, __VA_ARGS__); /
- }while(0)
- #else
- #define DBG(...)
- #endif
#define ERROR(...) /
do{ /
fprintf(stderr, "[ERROR ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
fprintf(stderr, __VA_ARGS__); /
}while(0)
#define WARNING(...) /
do{ /
fprintf(stdout, "[WARNING]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
fprintf(stdout, __VA_ARGS__); /
}while(0)
#define INFO(...) /
do{ /
fprintf(stdout, "[INFO ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
fprintf(stdout, __VA_ARGS__); /
}while(0)
#define SHOW_TIME(...) /
do{/
extern unsigned long long gLatestTime;/
timeval tp;/
gettimeofday(&tp, NULL);/
unsigned long long now = tp.tv_sec*1000000+tp.tv_usec; /
if(gLatestTime != 0) /
{ /
fprintf(stdout, ">>>>>>>>>Used Time: %s[%d], %s: %ld.%ld, %llu ms ", __FILE__, __LINE__, __func__, tp.tv_sec, tp.tv_usec, (now-gLatestTime)/1000);/
fprintf(stdout, __VA_ARGS__); /
fprintf(stdout, "/n"); /
} /
gLatestTime = now;/
}while(0)
#ifdef DEBUG
#define DBG(...) /
do{ /
fprintf(stdout, "[DEBUG ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /
fprintf(stdout, __VA_ARGS__); /
}while(0)
#else
#define DBG(...)
#endif
以上是定義的輸出文件信息,如果想輸出自定義的字符串(類似printf()的功能),可以使用可變參的形式傳遞。
如上面的的最後一個DEBUG的定義:
fprintf(stdout , __VA_ARGS__);
這行代碼使得用戶可以將自己的信息放在可變參裏面,例如:DBG(" I am from %s " , "ICT"); 這句話的輸出分成兩部分,前半部分打印文件名、函數名、行號,後半部分會輸出: I am from ICT 這句話。可變參給用戶提供了很好的自定義空間。
<將在下一篇博文中介紹一下" 可變參 "的用法>
說明:
stdout -- 標準輸出設備 (printf("..")) 同 stdout。
stderr -- 標準錯誤輸出設備 兩者默認向屏幕輸出。
但如果用轉向標準輸出到磁盤文件,則可看出兩者區別。stdout輸出到磁盤文件,stderr在屏幕。