c - 在宏中连接指向字符串文字的指针
问题描述
我需要在字符串的开头附加调用方的函数名称并用括号连接,所以它看起来像[<FUNCTION_NAME>] <string>
,但我得到[name] <string>
的是输出......可能它与#
字符串化传入的变量有关,但你怎么得到它工作吗?
#define FUN(STR) "["#STR"] "
void foo(const char *name, char *fmt, ...)
{
char buff[100] = {0};
va_list pList;
va_start(pList, fmt);
int ret = vsprintf(buff, fmt, pList);
va_end(pList);
char p[100] = {0};
sprintf (p, "%s%s", FUN(name), buff);
printf ("%s\n", p); // [name] Some string with value = 5
}
void bar()
{
foo(__func__, "Some string with value = %d", 5);
}
int main()
{
bar();
return 0;
}
解决方案
只需将括号放在 printf 格式字符串中。
printf("[%s]%s", name, buff)
但是有两个缓冲区听起来很浪费。只要有一个缓冲区。此外,代码需要防止过载。需要添加所需的检查以防止缓冲区溢出。另外,更喜欢使用snprintf
over sprintf
。
#define MIN(a, b) ((a)<(b)?(a):(b))
#ifdef __GNUC__
#if __GNUC__ > 10
__attribute__((__access__(read_only, 1)))
#endif
__attribute__((__format__(__printf__, 2, 3)))
#endif
void foo(const char *name, char *fmt, ...)
{
char buff[10];
char *p = buff;
const char *const end = buff + sizeof(buff);
// Add bracket.
static_assert(sizeof(buff) > 0, "");
*p++ = '[';
// Add name.
const size_t namelen = strlen(name);
size_t free = end - p;
// Leave space for 0 either way.
const size_t tocopy = MIN(free - 1, namelen);
memcpy(p, name, tocopy);
p += tocopy;
// Add "] ". Wonder, maybe it should be <=, not sure.
if (p < end - 1) {
*p++ = ']';
}
if (p < end - 1) {
*p++ = ' ';
}
// Add printf stuff
free = end - p;
if (free > 1) {
// It's odd that there is no vfoo(..., va_list va); overload.
va_list va;
va_start(va, fmt);
const int r = vsnprintf(p, free + 1, fmt, va);
va_end(va);
(void)r;
assert(r >= 0); // unneeded, pedantic: check errors
} else {
// Och, we remember about it.
assert(p < end);
*p = 0;
}
printf("%s\n", buff);
}
为什么宏观方法不起作用?
简而言之:宏适用于text。预处理器不存在变量,只有其他宏。对text#
应用#
操作,所以它变成,实际上调用变成了; name
"name"
sprintf (p, "%s%s", "[" "name" "] ", buff);
相邻"this" "that"
的字符串文字被连接在一起成为一个"thisthat"
,并%s
打印出来。
推荐阅读
- amazon-web-services - 如何使用ansible终止属于同一安全组的多个ec2实例?
- python - 有没有更快更有效的方法来保存 python 字典?
- python - 替换 Numpy 数组中的子数组
- python - 无法在文本框中输入输入(Python)
- algorithm - 给定一个 n 维点的无序列表,我怎样才能最好地找到由包围给定点的那些点中的 n+1 定义的最小体积?
- chef-infra - Inspec 中的模拟对象
- python - 如果在python中导入,PHP执行python代码不起作用
- javascript - 在 officejs 中插入段落后,集合中的段落范围已更改
- python-3.x - else 正在执行,而不在 for 循环中执行 if
- r - 如何重组此表以将所有行名转换为列名?