c语言中字符串比较指令,如何在C条件预处理器指令中比较字符串

CAVEAT:并非所有的编译器都以相同的方式实现C ++ 11规范。以下代码可在我测试过的编译器中使用,而许多注释者使用其他编译器。

引用Shafik Yaghmour的回答:在编译时计算C字符串的长度。这真的是constexpr吗?

不能保证在编译时就对常量表达式进行求值,但是从C ++标准草案第5.19节常量表达式中我们只能得到一个非规范性的引用,尽管如此:

[...]> [注意:常量表达式可以在翻译过程中求值。

这个词can改变了世界。

因此,YMMV对此问题(或任何问题)的涉及constexpr,取决于编译器作者对规范的解释。

[2016.01.31更新]

由于有些人不喜欢我之前的答案,因为它不需要字符串比较就可以实现目标,从而避免了compile time string compareOP 的整个方面,因此这里提供了更详细的答案。

你不能!不在C98或C99中。甚至在C11中也没有。大量的MACRO操作都不会改变这一点。

中const-expression使用的定义#if不允许使用字符串。

它确实允许使用字符,因此,如果您限制使用字符,则可以使用以下命令:

#define JACK 'J'

#define QUEEN 'Q'

#define CHOICE JACK     // or QUEEN, your choice

#if 'J' == CHOICE

#define USER "jack"

#define USER_VS "queen"

#elif 'Q' == CHOICE

#define USER "queen"

#define USER_VS "jack"

#else

#define USER "anonymous1"

#define USER_VS "anonymous2"

#endif

#pragma message "USER    IS " USER

#pragma message "USER_VS IS " USER_VS

您可以!在C ++ 11中。如果定义一个编译时辅助函数进行比较。

// compares two strings in compile time constant fashion

constexpr int c_strcmp( char const* lhs, char const* rhs )

{

return (('\0' == lhs[0]) && ('\0' == rhs[0])) ? 0

:  (lhs[0] != rhs[0]) ? (lhs[0] - rhs[0])

: c_strcmp( lhs+1, rhs+1 );

}

// some compilers may require ((int)lhs[0] - (int)rhs[0])

#define JACK "jack"

#define QUEEN "queen"

#define USER JACK       // or QUEEN, your choice

#if 0 == c_strcmp( USER, JACK )

#define USER_VS QUEEN

#elif 0 == c_strcmp( USER, QUEEN )

#define USER_VS JACK

#else

#define USER_VS "unknown"

#endif

#pragma message "USER    IS " USER

#pragma message "USER_VS IS " USER_VS

因此,最终,您将不得不改变实现为USER和选择最终字符串值的目标的方式USER_VS。

您不能在C99中进行编译时间字符串比较,但是可以进行字符串的编译时间选择。

如果确实必须进行编译时比较,则需要更改为允许该功能的C ++ 11或更高版本。

[原始答案]

尝试:

#define jack_VS queen

#define queen_VS jack

#define USER jack          // jack    or queen, your choice

#define USER_VS USER##_VS  // jack_VS or queen_VS

// stringify usage: S(USER) or S(USER_VS) when you need the string form.

#define S(U) S_(U)

#define S_(U) #U

更新:ANSI令牌粘贴有时不太明显。;-D

#在宏之前放置单个会导致将其更改为其值的字符串,而不是其裸值。

##在两个标记之间放置一个双精度值会使它们被串联为一个标记。

因此,宏USER_VS的扩展名为jack_VS或queen_VS,具体取决于您的设置方式USER。

该字符串化宏S(...)使用宏间接这样命名宏的值被转换成字符串。而不是宏的名称。

因此,USER##_VS成为jack_VS(或queen_VS),这取决于你如何设置USER。

稍后,当将stringify宏用作(在此示例中)S(USER_VS)的值时,将传递到间接步骤,该步骤会将其value()转换为string 。USER_VSjack_VSS_(jack_VS)queen"queen"

如果设置USER为,queen则最终结果是字符串"jack"。

有关令牌串联的信息,请参见:https : //gcc.gnu.org/onlinedocs/cpp/Concatenation.html

有关令牌字符串的转换,请参见:https : //gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值