歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C/C++中自定義信息輸出——printf與宏的配合使用

C/C++中自定義信息輸出——printf與宏的配合使用

日期:2017/3/1 9:43:20   编辑:Linux編程

在C/C++中,提起“宏”多少有些皺眉,至少我在入門C++時旁人好心提醒:盡可能地使用typedef與const常量定義來替代“宏”的使用:

1. 類型宏定義

#define HANLE void*
//可以替換為:
typedef void *HANLE;

2. 常量定義

#define MAX_LIMIT 4096
//可以替換為:
const int s_MAX_LIMIT 4096;

因為宏定義是在預編譯階段,對內容進行直接替換,因此無法提供安全的類型檢查等功能。

但我本次要說的是,宏的一個很炫的應用:

配合printf函數能夠方便地自定義輸出格式和內容。

舉例來說吧,就是用戶在程序中調用:

USER_PRINT( "i should checkout: v_a value is %d.\n", value_a );

能夠輸出類似信息

[2013-10-01 15:18:28][Fox Test][PID:2486]i should checkout: v_a value is 10.

當然,如果你用過linux下的syslog,你會發現這條輸出信息算是“高仿”了。syslog可是linux下調試/監控的優秀組件,簡單易用不說,功能也比較完備!

扯遠了,本次的目標就是如何在用戶簡單輸出一條信息的時候,我們能夠同時加上各種附加信息,包括時間/用戶/PID等參數,方便我們的調試/監控。

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

C++11 獲取系統時間庫函數 time since epoch http://www.linuxidc.com/Linux/2014-03/97446.htm

C++11中正則表達式測試 http://www.linuxidc.com/Linux/2012-08/69086.htm

1. 首先,提供一個有意思的宏,該宏也是該功能的核心

#define USER_PRINT_BASE( format, args... ) printf( format, ##args )

是不是看到args...有點兒蒙,以及##args又是鬧哪樣?

說明一下:

i: args...是一個參數,是C/C++中定義變參函數(參數不固定)的一種格式。至於舉個變參函數的例子,printf/scanf什麼的就是隨處可見的例子。

ii: ##args是宏的一個特殊語法應用(和普通的##宏應用不同[TODO]),使得宏展開時可以去掉可能存在的多余的','。

舉例:

當沒有##時,USER_PRINT_BASE( "something debug" )在宏展開時會成為printf( "something debug", )多了一個逗號!

當然,如果你調用USER_PRINT_BASE( "something debug--%d", 10 )的時候,即使沒有'##'也不會出錯。

iii: 如果你的編譯器支持C99規范,那麼宏也可以改寫為:

#define USER_PRINT_BASE( format, ... ) printf( format, ##__VA_ARGS__ )

嗯好吧,其實只是變參的書寫格式發生了點變化。

注:ii與iii詳細的可以參考“C/C++可變參數,“## __VA_ARGS__”宏的介紹和使用”,裡面有很詳細的介紹http://www.linuxidc.com/Linux/2014-06/102923.htm。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-06/102922p2.htm

Copyright © Linux教程網 All Rights Reserved