【问题标题】:Can `printf()` have a macro parameter? [duplicate]`printf()` 可以有宏参数吗? [复制]
【发布时间】:2021-06-12 12:57:07
【问题描述】:

我正在使用以下printf 函数:

    printf("%-8s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");

但是,我想使用预定义的宏来代替“8”:

#define NAME_SIZE 8

当我尝试替换它时,IDE 无法识别它并给出错误:Invalid conversion specifier N(宏的第一个字母)。我尝试将宏名称放在() 括号中或在这些括号中放置一个间隔,但也没有用。所以我想知道:甚至可以将宏作为参数放入printf 函数中,如果可以,如何?对于这么奇怪的问题,我很抱歉,但我找不到任何信息。

【问题讨论】:

  • 你试过编译吗?有时 IDE 会显示误报。
  • 如果你可以定义为"8",那么printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");会做你想做的事吗?
  • 您可以使用* 代替显式数字并将值作为int 参数传递到相应字符串之前:printf("%-*s%-21s%-17s%-6s\n", (int)(NAME_SIZE), "index", "Name", "Effect", "Type");
  • @Yunnosch 我将宏用于数组大小,所以它不能完全按照我想要的方式工作。不过还是谢谢你。
  • @chqrlie 这就是我需要的!谢谢!

标签: c++ c macros printf


【解决方案1】:

是的,您确实可以这样做(尽管在您的特定情况下,您可以传递参数宽度,这是一种更好的方法)。事实上,一些 C 和 C++ 的标准库利用了这一点(或者换句话说,将其批准为合法技术),例如使用 PRId64 来正确格式化 int64_t:

#include <inttypes.h>
int64_t t = 0;
printf("%" PRId64 "\n", t);

在你的情况下,你需要

#define NAME_SIZE "8"

随着

printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");

【讨论】:

    【解决方案2】:

    假设您可以稍微不同地定义宏:

    如果您可以定义为#define NAME_SIZE "8",那么printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type"); 将按照我的理解来做您的目标。

    这是因为编译器会将直接相邻的字符串文字(如"a""b")连接到"ab"

    如果宏必须完全如图所示,您必须通过在另一个级别的宏中使用# 运算符来绕道。

    【讨论】:

      【解决方案3】:

      您可以通过以下方式进行操作

      #include <stdio.h>
      
      #define SIZE( X )   #X
      
      int main(void) 
      {
          printf("%-" SIZE( 8 ) "s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");
          printf("%-8s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");
          
          return 0;
      }
      

      程序输出是

      index   Name                 Effect           Type  
      index   Name                 Effect           Type
      

      【讨论】:

      • 我觉得不错。那么X 也可以在别处用作整数常量。 #define X 8 printf("pi to %d places: %." SIZE( X ) "f\n", X+1, X, acos(-1)); 以恒定精度打印 pi。这对于scanf()printf() 更有价值,尽管printf() 有一个width 说明符选项。
      猜你喜欢
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2018-03-04
      • 2023-01-28
      • 2018-02-07
      • 1970-01-01
      • 2023-02-25
      相关资源
      最近更新 更多