昨天做輸出系統的時候,發現輸出Vector2這樣常見的結構,沒有一個通用的函式直接轉成字串。再往回看,好像沒有做過Log功能欸,雖然直接使用printf
也可以,但既然都要重頭開始了,那就做出一個簡單的log功能吧~!
printf
int printf( const char* format, ... )
最開始學的時候就很好奇,為什麼C語言的功能很簡單(相對其他語言),但printf
可以帶這麼多參數進去,之前沒想那麼多,想說能用就好了,今天就趁這個機會來解析一下到底是做了甚麼,而這個秘密就在那個...
裡面。
那個叫做Variadic functions(我不知道中文怎麼翻),它可以讓我們N個參數,那要怎麼讓函式變成可以有N個參數呢?答案就在stdarg.h
的腳本裡面。
其中:
之後就可以用這三個,寫出一個極簡單的Log功能
void LogMessage(LogT log_type, const char* file_name, int line, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
fprintf(stdout, "%s %s:%d ", LOG_LABELS[log_type], file_name, line);
vfprintf(stdout, fmt, args);
fprintf(stdout, "\n");
va_end(args);
}
上面的va_start
就等於是,從參數列fmt開始,讀後面開始的任意得參數。
可以看到著函式還要印出「哪個文件」和「第幾行開始」,這就可以簡單的用上C語言內建的marco:
__FILE__、__LINE__
直接把相對的把這個功能做出來。
然後再依靠LogMessage
,改成macro function,最後就可以做出不同階級的log囉
#define LogInfo(...) LogMessage(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__);
#define LogWarning(...) LogMessage(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__);
#define LogError(...) LogMessage(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__);
至於macro function中的...跟__VA_ARGS__(注意: 是兩條底線喔),是甚麼呢?
__VA_ARGS__是個macro,等於這個函式任意任數量的參數,簡單來說,上面的code就表示
... == (const char* fmt, ...)