C 宏中字符串和数字的混合

C 宏中字符串和数字的混合,c,string,macros,numbers,C,String,Macros,Numbers,我想使用此宏将符号“^”和我传递给宏的数字(I)放入(如果“I”大于零) #define ESP(i) ((i>0) ? ("^"(i)) : "") 我想这样称呼它 printf("%+d%s", n1, ESP(i)); 其中“i”是一个周期的索引,但汇编报告了我的错误; 如何修改代码使其正确?您不需要在“^”后面加上(I)。将您的宏更改为此,它应该可以工作#定义ESP(i)((i>0)?(^”):(“”)。然后,在printf语句中,如果要在“^”后面打印i的值,则可以使用类似以

我想使用此宏将符号“^”和我传递给宏的数字(I)放入(如果“I”大于零)

#define ESP(i) ((i>0) ? ("^"(i)) : "")
我想这样称呼它

printf("%+d%s", n1, ESP(i));
其中“i”是一个周期的索引,但汇编报告了我的错误;
如何修改代码使其正确?

您不需要在“^”后面加上(I)。将您的宏更改为此,它应该可以工作
#定义ESP(i)((i>0)?(^”):(“”)
。然后,在printf语句中,如果要在“^”后面打印i的值,则可以使用类似以下内容的printf(“%s%d”,ESP(i),i)据我所知,我不认为可以将字符串格式化为在宏中包含整数,因为这需要调用其他函数,所以必须将I放入printf中的字符串中

有点脏,但应该可以:

#include <stdio.h>

#define DYNFORMAT(n, i) (i>0) ?"%+d%s%d\n" :"%+d%s%s\n", n, (i>0) ?"^" :"", (i>0) ?i :""

int main(void) 
{
  int i = 0;
  printf(DYNFORMAT(42, i));
  i = 1;
  printf(DYNFORMAT(42, i));
}
免责声明:我不确定这是否符合标准,以及如何消除编译过程中给出的警告


干净的方法是使用两个调用
printf()

这可以实现为宏或函数

由于我喜欢前置处理器,这里的宏版本:

#define PRINT_ESP(n, i) \
do { \
  if (i = 0) \
    printf("%+d", n); \
  else \
    printf("%+d^%d", n, i); \
} while (0); 

宏在编译时运行,而不是在运行时。它们可以执行各种文本篡改技巧,但它们不评估任何内容。(但是,它们当然可以扩展到计算某事物的代码。)将变量
i
的格式化值放入字符串中涉及计算
i
;没有宏可以做到这一点

您可以扩展宏的范围,以包括整个
printf()
调用:

#define PRINT_ESP(n1, i) do { \
    printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)
或者,您可以使用宏来表示上述宏定义中包含的格式选择,也可以将上面的完整
printf()
调用直接放入代码中


所有这些变化都是基于这样一个事实,即超过给定格式所需参数的参数在调用之前进行求值,但被
printf()
本身忽略。

“您不需要(i)…。”就我理解的问题而言,
i
的(值)是一个明确的必选项。不,他希望
i
的值出现在宏展开中。哦,我的错从他的解释中我想他只是想要打印“^”,好的,让我删除这个答案,然后我想他必须将i打印到printf中,因为将其留在宏中会导致编译错误,所以我编辑了答案。抱歉造成混淆请注意,
(i)
不等同于
(i>0)
,如果
i
是有符号类型。好的,当然可以。但这是一个细节。但是,我们将纠正这一点@约翰伯林格瑞我想象你的警告来自这样的表达:
(i>0)?i:
。如果从第二个格式字符串中删除尾随的
%s
字段描述符,则可以避免警告并将该表达式更改为普通的
i
。这将不起作用,至少因为
%s
需要一个参数列表中不存在的“字符串”。更直截了当的是,我的答案。也更干净,因为它产生的警告很少。
#define PRINT_ESP(n1, i) do { \
    printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)