如何用C可变参数宏生成终端字体效果转义码?
用可变参数宏实现终端字体效果转义码生成
完全可以用可变参数宏实现这个需求,不过C预处理器本身没有像sed那样直接全局替换分隔符的功能,得用点预处理器技巧绕开这个问题,下面给两种可行的实现方式:
方法一:基于C23标准的递归宏实现
这种方法利用C23新增的__VA_OPT__特性,能优雅处理任意个数的参数(需编译器支持C23):
// 递归辅助宏:逐个处理参数,用分号分隔 #define _FONT_FX_HELPER(first, ...) #first __VA_OPT__(;) _FONT_FX_HELPER(__VA_ARGS__) // 终止递归的空宏 #define _FONT_FX_END() // 重定向宏,避免空参数触发错误 #define _FONT_FX_REDIRECT(...) _FONT_FX_HELPER(__VA_ARGS__, _FONT_FX_END()) // 主可变参数宏 #define FONT_FX(...) "\x1b[" _FONT_FX_REDIRECT(__VA_ARGS__) "m"
工作逻辑:
_FONT_FX_HELPER递归遍历每个参数,把参数字符串化后,仅当还有后续参数时才添加分号(靠__VA_OPT__(;)实现)- 最后拼接终端转义序列的首尾部分,生成完整控制码
方法二:兼容C99的参数计数宏实现
如果你的编译器还不支持C23,可以用这种基于参数个数判断的方法,支持有限个数的参数(可按需扩展):
// 针对不同参数个数的辅助宏 #define _FONT_FX_1(a) #a #define _FONT_FX_2(a,b) #a ";" #b #define _FONT_FX_3(a,b,c) #a ";" #b ";" #c #define _FONT_FX_4(a,b,c,d) #a ";" #b ";" #c ";" #d // 若需要更多参数,继续添加类似的_FONT_FX_N宏即可 // 预处理器技巧:计算参数个数 #define _COUNT_ARGS(...) _COUNT_ARGS_(__VA_ARGS__,4,3,2,1,0) #define _COUNT_ARGS_(a,b,c,d,e,n,...) n // 主宏:根据参数个数调用对应辅助宏 #define FONT_FX(...) "\x1b[" _FONT_FX_##_COUNT_ARGS(__VA_ARGS__)(__VA_ARGS__) "m"
工作逻辑:
_COUNT_ARGS通过预处理器的参数展开特性,计算出传入的参数个数- 然后通过宏拼接
_FONT_FX_##个数,调用对应参数个数的辅助宏,生成用分号分隔的参数字符串
使用示例
不管用哪种方法,使用方式都和你之前的双/三参数宏一致:
// 示例字体效果枚举 typedef enum { FG_RED = 31, BG_YELLOW = 43, BOLD = 1, ITALIC = 3 } FontEffect; // 调用可变参数宏 #include <stdio.h> int main() { printf("%s加粗红底黄字%s\n", FONT_FX(BOLD, FG_RED, BG_YELLOW), "\x1b[0m"); printf("%s斜体红%s\n", FONT_FX(ITALIC, FG_RED), "\x1b[0m"); return 0; }
内容的提问来源于stack exchange,提问作者spubby
相关产品推荐
相关产品推荐

