【问题标题】:C preprocessor define to replace string format specifierC 预处理器定义替换字符串格式说明符
【发布时间】:2018-05-29 14:32:25
【问题描述】:

我想知道是否可以使用 C 预处理定义来更改字符串格式说明符。我尝试编写以下内容,但似乎遇到了编译器错误。它只是试图用正确的格式说明符替换现有的格式说明符。

#include <stdio.h>

//This is the problem line....
#define %d %llu    

int main(int argc, char** argv){
    unsigned long long int myInt = 0;

    printf("myInt start value: %d", myInt++);
    printf("myInt value=%d (that got incremented)", myInt++);
    printf("myInt value: %d; wow, another post-increment", myInt++);
    printf("myInt final value %d", myInt);

    return 0;    
}

我收到以下编译器错误:

error: expected an identifier
  #define %d %llu
          ^

为什么这种语法不可接受?有没有可能实现?

【问题讨论】:

  • 1.您不能用%d 命名宏——它不是合法的C 标识符。 2. 即使可以 - 宏也不会在 C 字符串文字中替换。 3. 对于int 类型的每个变体,都有匹配的格式化程序,它们在相应的位置上被正确解释。平台。因此,甚至不需要这个宏技巧。
  • 宏不是这样工作的。除了遵守与 C 相同的符号名称规则外,您还可以在字符串文字中进行宏替换。
  • 旁白:%lliunsigned long long 的错误格式说明符。应该是%llu

标签: c string format preprocessor specifier


【解决方案1】:

你想做的事情是不可能的。

宏不会在字符串文字中被替换,有效标识符名称的规则也适用于宏名称。

你可以这样做:

#if xyz
  #define FMT   "%d"
#else
  #define FMT   "%lli"
#endif

....

printf("myInt start value: " FMT "\n", myInt++);

顺便说一句: 通常你不需要这个。对于原生类型intlong 等,格式说明符应该可以正常使用。

对于固定大小的类型(例如int64_t 等),inttypes.h 中已经定义了宏

【讨论】:

  • 我对宏的理解有问题!谢谢你的澄清
【解决方案2】:

有可能实现吗? 不,你现在的方式不可能。在声明中

#define %d %lli 

宏名必须是有效的标识符

来自C99 标准

第 6.10.1 节

# define identifier replacement-list new-line

从 7.1.13 开始

  • 以下划线和大写字母或另一个下划线开头的所有标识符始终保留给任何 使用。
  • 以下划线开头的所有标识符始终保留用作标识符 在普通名称空间和标记名称空间中都具有文件范围。
  • 以下任何子条款中的每个宏名称(包括未来库 如果包含任何关联的标头,则保留用于指定用途; 除非另有明确说明(参见 7.1.4)。

宏名设为有效标识符。例如,将宏定义为

#define INT_FMT "%d"

然后

 int myInt = 10;
 printf("myInt start value is : "  INT_FMT  "\n", myInt);

【讨论】:

    猜你喜欢
    • 2015-10-04
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    相关资源
    最近更新 更多