2012年8月3日 星期五

如何將巨集轉為字串

在c/c++的程式裡面用#define定義的東西,要怎麼變成字串呢?

c/c++裡面有個字串化的運算子#(stringizing operator),可以把巨集的參數轉換成字串常數。如下的簡單範例所示,定義了幾個簡單的巨集,利用#運算子就能把任何東西轉換成字串。

#define TOSTR2(s) #s
#define TOSTR2W(s) L#s
#define TOSTR(tok) TOSTR2(tok)
#define TOSTRW(tok) TOSTR2W(tok)

#define min(a,b) (a) < (b) ? (a) : (b)

int main()
{
    int i = min(min(4,2), 3);

    char *s1 = TOSTR2(min(min(4,2), 3));
    wchar_t *ws1 = TOSTR2W(min(min(4,2), 3));

    char *s2 = TOSTR(min(min(4,2), 3));
    wchar_t *ws2 = TOSTRW(min(min(4,2), 3));

   return 0;
}

在程式的設定裡,打開/P參數可以將巨集展開後的結果另外輸出成檔案,我們可以由這個檔案來觀察一些有趣的結果。


底下是輸出結果的片段。


int main(void)
{
    int i = ((4) < (2) ? (4) : (2)) < (3) ? ((4) < (2) ? (4) : (2)) : (3);

    char *s1 = "min(min(4,2), 3)";
    wchar_t *ws1 = L"min(min(4,2), 3)";

    char *s2 = "((4) < (2) ? (4) : (2)) < (3) ? ((4) < (2) ? (4) : (2)) : (3)";
    wchar_t *ws2 = L"((4) < (2) ? (4) : (2)) < (3) ? ((4) < (2) ? (4) : (2)) : (3)";

    return 0;
}

可以看到s1使用TOSTR2作展開,因為TOSTR2使用了#運算子,所以只把代入的參數轉為字串,此例中為min(min(4,2), 3)。如果還要將min(min(4,2), 3)作最終的完全展開內容轉為字串的話,則需要再加一層巨集,使用TOSTR。TOSTR將min(min(4,2), 3)代入後,由preprocessor展開後再當作參數再代TOSTR2,這時就能得到完全展開的字串結果。

要轉換成unicode字串則使用xxxW版本的巨集作展開。

Related Posts Plugin for WordPress, Blogger...