带有L标识符的#define语法

时间:2012-04-07 04:08:44

标签: c++ c winapi c-preprocessor widechar

#define CONST_FILENAME "okay.dat"
LPCWSTR lpFilename=L CONST_FILENAME; //obviously doesn't work

基本上,我如何得到相当于:

LPCWSTR lpFilename=L"okay.dat";

使用#define

3 个答案:

答案 0 :(得分:5)

#define GLUE(x,y) x##y
#define W(x) GLUE(L,x)

#define CONST_FILENAME "okay.dat"

int main() {
    const wchar_t* lpFilename = W(CONST_FILENAME);
    const wchar_t* lpFilename = W("okay.dat");
    wchar_t one_character = W('?');
}

http://ideone.com/2EzB6的汇编证明。这正是微软的_T宏的工作原理,除了我无条件地定义它,因此即使不在MSVC“Unicode”构建中,也可以使用它来获取宽字符串。至于为什么需要GLUE宏,我从来没有听过对我有意义的解释,但如果没有它,宏将不会扩展,所以它是必需的。看起来有详细信息:What are the applications of the ## preprocessor operator and gotchas to consider?

答案 1 :(得分:3)

#define CONST_FILENAME L"okay.dat"

答案 2 :(得分:2)

  

但是如果我想在ASCII上下文[也]中使用CONST_FILENAME怎么办?如:

char *something = CONST_FILENAME;

L中的L"okay.dat"无法通过空格与"分隔。宽字符串是一个令牌,您无法直接“向其添加L”。但是,你可以进行字符串连接:

#include <wchar.h>

#define A_STRING "xyz.txt"

/* MMT - Magical Mystery Tour */
#define MMT(x) L"" x

char a[] = A_STRING;
wchar_t w[] = MMT(A_STRING);

狡猾,但海湾合作委员会对它没问题。那很好,因为标准也是如此。这来自C99标准:

  

§6.4.5字符串文字

     

¶4在翻译阶段6中,由任何序列指定的多字节字符序列   相邻字符和宽字符串文字标记连接成单个多字节   字符序列。如果任何令牌是宽字符串文字标记,则产生   多字节字符序列被视为宽字符串文字;否则,它被视为一个   字符串文字。


测试代码:

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>

#define A_STRING "xyz.txt"

/* MMT - Magical Mystery Tour */
#define MMT(x) L"" x

static char a[] = A_STRING;
static wchar_t w[] = MMT(A_STRING);

int main(void)
{
    int len1 = wcslen(w);
    int len2 = sizeof(w) / sizeof(w[0]) - 1;
    int len3 = strlen(a);
    int len4 = sizeof(a) / sizeof(a[0]) - 1;

    assert(len1 == len2);
    assert(len3 == len4);
    assert(len1 == len3);
    printf("sizeof(a) = %zu; sizeof(w) = %zu\n", sizeof(a), sizeof(w));

    for (int i = 0; i < len1; i++)
        printf("%d = %d\n", i, (int)w[i]);

    for (int i = 0; i < len1; i++)
        printf("%d = %d\n", i, (int)a[i]);

    return(0);
}

汇编:

gcc -O3 -g -Wall -Wextra -std=c99  xx.c -o xx  

示例输出:

sizeof(a) = 8; sizeof(w) = 32
0 = 120
1 = 121
2 = 122
3 = 46
4 = 116
5 = 120
6 = 116
0 = 120
1 = 121
2 = 122
3 = 46
4 = 116
5 = 120
6 = 116

测试平台

MacOS X 10.7.3(Lion)。 64位编译。

  

i686-apple-darwin11-llvm-gcc-4.2(GCC)4.2.1(基于Apple Inc. build 5658)(LLVM build 2335.15.00)