【问题标题】:How to convert #defined string literal to a wide string literal? [duplicate]如何将#defined 字符串文字转换为宽字符串文字? [复制]
【发布时间】:2014-12-05 12:10:18
【问题描述】:

可能重复:
How to convert concatenated strings to wide-char with the C preprocessor?

我有一个使用#define 定义的字符串文字:

#define B "1234\0"

如何在编译时使用这个定义来获取这个宽字符串?:

L"1234\0"

(只是 #defined 字符串文字加上 L 前置以使其成为宽字符串)。

我试过了:

#define MAKEWIDE(s) L##s

但这会生成LB

【问题讨论】:

  • 另请注意,您通常不需要将 '\0' 字符放在文字字符串的末尾 - 编译器会为您完成。我唯一能想到的时候你需要自己做的是,如果你真的需要在你的字符串末尾有两个空字符,或者你需要确保用文字初始化的字符数组得到空终止字符 - 在C,大小合适的 char 数组不会得到空字符。自己显式地添加它会鼓励编译器至少生成一个警告。这两种用途都很少有用。
  • 我预计有人会提到\0。我不对字符串文字负责,也不清楚它为什么存在。

标签: c c-preprocessor


【解决方案1】:

标记粘贴需要额外的间接级别来正确处理用作操作数的宏。尝试类似:

#define PASTE(x, y) x##y
#define MAKEWIDE(x) PASTE(L,x)

【讨论】:

  • 什么过于复杂 - 为此使用宏,或者必须通过辅助宏间接标记粘贴?用于令牌粘贴的辅助宏通常是获得预期结果所必需的。因此,一般来说,如果在项目的其他任何地方使用令牌粘贴,应该已经存在这样的辅助宏。
  • 我的意思是,无论如何,根据标准 C,简单的字符串连接应该在没有任何预处理器技巧的情况下处理它。
【解决方案2】:

这会很好用:

#define B "1234\0"
#define LB L"" B

【讨论】:

  • 聪明。不过,我必须进行一些挖掘——我记得在其他地方看到过这个描述(我已经忘记了),但我记得有些编译器无法处理它。
  • OK - MSVC 做不到:错误 C2308: concatenating mismatched strings Concatenating wide "" with narrow "1234"
  • 该领域的标准从 C90 更改为 C99 - 在 C90 中,它被称为未定义行为; C99 对此进行了更改,以便将文字“转换”为宽字符字符串文字。由于 MS 从未支持 C99,因此这种行为是可以理解的……
  • 啊,我认为这种行为可以追溯到宽字符串的开头..
  • 只是 2016 年的一条消息... VS2015 行为正确。现在我们是 99 之后的 17 年,我建议这是最好的答案,除非你正在处理一个非常神秘的平台。
猜你喜欢
  • 2012-05-16
  • 1970-01-01
  • 2017-04-16
  • 2011-10-05
  • 1970-01-01
  • 2014-08-05
  • 2015-08-17
相关资源
最近更新 更多