[英]How to concatenate a character constant into a string. C
如果我在 C 中定義了一個常量字符,我可以將它連接成一個字符串文字嗎?
#ifdef WIN32
# define SEP '\\'
# define ALTSEP '/'
#else
# define SEP '/'
# define ALTSEP '\\'
#endif
#define SOME_STRING_LITERAL "foo"
/* code snippet */
/* Desired string: "prefix_foo/bar" */
const char *path = "prefix_" SOME_STRING_LITERAL SEP "bar";
當然這失敗了,因為SEP
沒有定義為字符串文字,但是有什么方法可以使SEP
正確連接? 或者我需要另一個定義,例如#define SEP_STR "/"
。
我認為你不能在 C 中做到這一點。
核心問題是"
符號是如此基本的東西,甚至在預處理器知道它應該將什么視為預處理標記之前,它就被解釋了。
使用 # 運算符進行字符串化無濟於事。 即使你寫了一個宏
#define STRINGINIZE(x) #x
#define CHAR_TO_STR(ch) STRINGINIZE(ch)
然后將其調用為
const char *path = "prefix_" SOME_STRING_LITERAL CHAR_TO_STR(SEP) "bar";
它對你沒有好處,因為你最終會得到一個像
prefix_foo`\`bar
你也不能這樣做:
const char *path = "prefix_" SOME_STRING_LITERAL CHAR_TO_STR(SEP)[1] "bar";
因為它與我們最初擁有的相同,並且不會編譯。
此外,您不能基於連接預處理器標記來制定解決方案,因為"
是比##
更基本的符號。
所以唯一的解決方案似乎是將字符聲明為字符串文字。
您可以使用編譯時字符串化運算符#
#define SEP_STR(x) #x
#define SEP_STR_2(x) SEP_STR(x)
const char *path = "prefix_" SOME_STRING_LITERAL SEP_STR_2(SEP) "bar";
或者您可以將SEP
定義為"\\\\"
。
由於此鏈接中很好地解釋的原因,需要雙級 MACRO 擴展
簡而言之:
如果要對宏參數的展開結果進行字符串化,則必須使用兩級宏。
不是將 SEP 定義為字符,而是將其定義為字符串。
#include <stdio.h>
#define SEP "\\"
#define SOME_STRING_LITERAL "foo"
int main() {
const char * path = "prefix_" SOME_STRING_LITERAL SEP "bar";
puts(path);
return 0;
}
輸出: prefix_foo\\bar
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.