我有一个必须用C语言完成的编码任务。我偏离了主题,决定尝试制作一个格式宏,可以用ANSI代码对文本进行样式化。我的代码如下:
<format.h>
#include <stdarg.h>
#include <string.h>
/**
* global buffer to store format arguments for prints
*/
char format_buffer[128];
/**
* Count the number of char* in variadic arguments, auxiliary for FMT macro
*/
#define FARGS(...) (sizeof((char*[]){__VA_ARGS__})/sizeof(char*))
/**
* Automatically fills in parameters buffer and argc for the format function. Buffer is a global variable, therefore it is never out of scope.
*/
#define FMT(...) format(format_buffer, FARGS(__VA_ARGS__), __VA_ARGS__)
#define A_START "\x1B["
#define A_END "m"
/**
* creates a format string based on input parameters.
* @param argc the number of ansi flags to use
* @param buffer the buffer to write the format string into. A size of 64 should be enough for most reasonable uses
* @param ... the ansi flags to use. Examples include RED, BLUE, DASH, etc
* @return the same pointer buffer, for ease of use in printf functions
*/
char* format(char* buffer, int argc, ...);
// ansi macros for formatting, all of the style ";NN"
<format.c>
#include "format.h"
char format_buffer[128] = {};
char* format(char* buffer, int argc, ...){
buffer[0] = '\0';
va_list argv;
int i;
// initialize argv to get data from the variable arguments
va_start(argv, argc);
strcat(buffer, A_START);
/* access all the arguments assigned to valist */
for (i = 0; i < argc; i++) {
strcat(buffer, va_arg(argv, char*));
}
strcat(buffer, A_END);
/* clean memory reserved for valist */
va_end(argv);
return buffer;
}
使用它,我可以如下调用宏,这就是我想要的:printf("%sHello!\n", FMT(RED, BOLD)) //prints <Hello!\n> in red and bold
∮问题是
我遇到的问题是,当我试图在同一个print语句中使用多个调用时:printf("%sHello, %sWorld!\n", FMT(RED, BOLD), FMT(YELLOW)) //prints <Hello, World!\n> in yellow
我肯定它没有像预期的那样工作,因为FMT(...)
总是返回相同的全局char *,但我不知道如何更改它,以便:
- 我可以调用如上所示的格式宏:
printf("%sHello!\n", FMT(RED, BOLD))
. - 我可以在同一个print语句中使用多个FMT调用,例如
printf("%sHello, %sWorld!\n", FMT(RED, BOLD), FMT(YELLOW))
应该用红色和粗体打印〈Hello,〉,用黄色打印〈World!\n〉。
作为最后一点说明,我宁愿编写解决方案,而不是使用已经实现了它的库或头文件。
我第一次尝试在format函数中创建一个新的char [],但是它会存储在堆栈中,所以我认为这是一个更糟糕的结果。
2条答案
按热度按时间hc2pp10m1#
只需将宏更改为:
https://godbolt.org/z/KvWWcYfPb
aamkag612#
在阅读了Jonathan Leffler的注解和0___________的答案后,我将文件更改为:
<format.h>
<format.c>
宏按预期工作,如果超过格式缓冲区容量,格式函数现在将提前停止阅读参数(缓冲区的长度必须至少为4,我相信最长的单个ANSI代码是4个字符长)。