是否可以使用预处理器(宏)将C字符串文字转换为大写?

是否可以使用预处理器(宏)将C字符串文字转换为大写?,c,macros,c-preprocessor,C,Macros,C Preprocessor,忽略了有时有更好的非宏方法可以做到这一点(遗憾的是,我有很好的理由),我需要使用宏编写大量通用代码。本质上是一个宏库,它将为某些预先指定的类型生成大量函数 为了避免破坏大量预先存在的单元测试,库必须做的一件事是,对于每个类型,在所有CAP中生成该类型的名称以便打印。例如,“标志”类型必须打印为“标志” 我可以手动写出每种类型的常量,例如 #定义标志\u ALLCAPSNAME标志 但这并不理想。我希望能够做到这一点编程 目前,我已经将其整合在一起: char capname_buf[BUFSIZ

忽略了有时有更好的非宏方法可以做到这一点(遗憾的是,我有很好的理由),我需要使用宏编写大量通用代码。本质上是一个宏库,它将为某些预先指定的类型生成大量函数

为了避免破坏大量预先存在的单元测试,库必须做的一件事是,对于每个类型,在所有CAP中生成该类型的名称以便打印。例如,“标志”类型必须打印为“标志”

我可以手动写出每种类型的常量,例如

#定义标志\u ALLCAPSNAME标志

但这并不理想。我希望能够做到这一点编程

目前,我已经将其整合在一起:

char capname_buf[BUFSIZ];
#define __MACRO_TO_UPPERCASE(arg) strcpy(capname_buf, arg); \
 for(char *c=capname_buf;*c;c++)*c = (*c >= 'a' && *c <= 'z')? *c - 'a' + 'A': *c;
__MACRO_TO_UPPERCASE(#flag)
char capname_buf[BUFSIZ];
#定义从宏到大写(arg)的strcpy(capname\u buf,arg)\

对于(char*c=capname_buf;*c;c++)*c=(*c>='a'&&&*c),在便携式C99中不可能有一个将常量字符串转换为所有大写字母的宏(特别是因为字母的概念与字符编码有关。UTF8字母与ASCII字母不同)

但是,您可以考虑其他的解决方案。

  • 自定义编辑器来实现这一点。例如,您可以编写一些emacs代码,根据需要更新每个C源文件

  • 在C源代码上使用一些预处理器(可能是一个简单的C代码生成器脚本,它会在一些
    \include
    -d文件中发出一堆
    \define

  • 过去也许有

    #define TO_UPPERCASE_COUNTED(Str,Cnt)
    #define TO_UPPERCASE(Str) TO_UPPERCASE_COUNTED(Str,__COUNT__) {( \
       static char buf_##Cnt[sizeof(Str)+4]; \
       char *str_##Cnt = Str; \
       int ix_##Cnt = 0; \
       for (; *str_##Cnt; str_##Cnt++, ix_##Cnt++) \
         if (ix_##Cnt < sizeof(buf_##Cnt)-1) \
             buf_##Cnt[ix_##Cnt] = toupper(*str_##Cnt); \
       buf_##Cnt; )}
    
    #定义为_大写_计数(Str,Cnt)
    #定义TO_大写字母(Str)TO_大写字母(Str,u计数){\
    静态字符buf#Cnt[sizeof(Str)+4]\
    char*str###Cnt=str\
    int ix##Cnt=0\
    对于(;*str##Cnt;str##Cnt++,ix#Cnt++)\
    if(ix##Cnt
  • <> LI> < P>定制GCC,也许使用(特定领域的语言来扩展GCC),提供您的C++代码。
完全使用c预处理器是不可能做到这一点的。原因是预处理器将输入读取为(原子)
pp标记
,并从中构成输出。预处理器没有任何结构可以将
pp标记
以任何方式分解为单个字符(无论如何,没有人会在这里帮助你)

在您的示例中,当预处理器读取字符串literal
“flag”
时,它对预处理器来说基本上是一个原子文本块。它有一些构造可以有条件地删除这些文本块或将它们粘合在一起形成更大的文本块

在某种意义上,唯一允许您分解
pp令牌的构造是通过一些表达式。但是这些表达式只能处理算术类型,这就是为什么它们在这里对您没有帮助


您的方法通过使用C语言构造(即在运行时进行转换)来避免这个问题。然后预处理器所做的唯一事情就是插入C代码来转换字符串。

我看到@unwind可能重复,但答案不正确(因此没有用)b/c它假设您不能在预处理器中进行循环(您可以).怎么做?您的示例没有显示预处理器完成的循环,如果您知道如何做,这不应该是您的起点吗?可能一个重要的限制是C宏无法将令牌拆分为较小的令牌,只能粘贴或字符串化它们以生成较大的令牌。因此预处理器无法对ind进行操作IVI您的类型名称的双字符
flag
。但是,除了标准要求之外,还有其他(更强大的)C预处理器可用。我认为这个答案可能重复涵盖了几乎所有的选择。谢谢。