Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ #使用L标识符定义语法_C++_C_Winapi_C Preprocessor_Widechar - Fatal编程技术网

C++ #使用L标识符定义语法

C++ #使用L标识符定义语法,c++,c,winapi,c-preprocessor,widechar,C++,C,Winapi,C Preprocessor,Widechar,基本上,我如何获得以下等价物: #define CONST_FILENAME "okay.dat" LPCWSTR lpFilename=L CONST_FILENAME; //obviously doesn't work 使用#定义?#定义常量文件名L“okay.dat” 但如果我想在ASCII上下文中使用CONST_FILENAME,该怎么办?例如: LPCWSTR lpFilename=L"okay.dat"; L“okay.dat”中的L不能用空格与“分开。宽字符字符串是单个标记,您

基本上,我如何获得以下等价物:

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

#定义常量文件名L“okay.dat”

但如果我想在ASCII上下文中使用
CONST_FILENAME
,该怎么办?例如:

LPCWSTR lpFilename=L"okay.dat";
L“okay.dat”
中的
L
不能用空格与
分开。宽字符字符串是单个标记,您不能直接“向其添加
L
”。但是,您可以执行字符串串联:

char *something = CONST_FILENAME;
示例输出: 试验台 MacOS X 10.7.3(Lion)。64位编译

i686-apple-darwin11-llvm-gcc-4.2(gcc)4.2.1(基于苹果公司的构建5658)(llvm构建2335.15.00)


编译证明在。这正是Microsoft的
\u T
宏的工作原理,除非我无条件地定义它,这样即使不是在MSVC“Unicode”中,您也可以使用它来获取宽字符串“建造。至于为什么需要GLUE宏,我从来没有听过一个对我有意义的解释,但是没有它宏就不会扩展,所以它是必需的。这里似乎有一些细节:

对VC++不太熟悉,但我相信(CONST_FILENAME)应该可以工作。如LPCWSTR fn=\u T(常量文件名);错误:“\T”标识符未找到。是的,我包括在内,而且仍然是。我知道我在这里做错了什么。一个快速的谷歌显示它是在tchar中定义的。幸运的是,它还将把你束缚在Windows上。我相信T和文本不是标准的。我已经在谷歌上搜索了一段时间,但似乎不知道如何以符合标准的方式进行搜索。@corbin:\t是一个与其他宏类似的宏。如果没有定义,请自己定义。现在它符合标准。但是如果我想在ASCII上下文中使用CONST_文件名呢?例如
char*something=CONST\u FILENAME
?宽字符串是另一种类型。将其复制到平台的宽字符类型。POSIX具有wchar\t。wchar_t s[99];wcscpy(s,CONST_文件名);不确定Windows,可能是WCHAR?也可以使用库或特定于实现的转换函数将文件名转换为字符,这样可能会丢失一些字符/file not found错误。只需在Visual Studio 2008和2010中尝试此操作。在这两种情况下,我都会遇到编译器错误:
“错误C2308:将不匹配的字符串串接为宽”“与窄的”xyz.txt”“
。根据OP使用的
LPCWSTR
typedef,我推断他们使用的是Windows(很可能是Visual Studio)。由于标准明确允许这种语法,这是MSVC中的一个错误。可能这是一个已知的问题,“问题”(或“原因”)可能是MSVC没有声明遵守C99标准。我不记得C89在连接宽字符串和非宽字符串时说了什么。Doh!不知何故,我漏掉了C99位。@JonathanLeffler:C89/C90标准明确表示行为未定义。(因此MSVC可以在不违反C99标准的情况下实现C99语义。)@KeithThompson:你的意思是“可以在不违反C89标准的情况下实现C99语义”吗?如果是这样,我同意他们可以,但从安德烈的评论来看,微软选择不实现C99语义,而是选择生成错误。真遗憾。甚至令人讨厌。(事实上,微软没有实现C99在很大程度上使编写必须在Windows和Unix上运行的现代代码变得相当困难。我感到沮丧的是,我被22年的技术而不是13年的技术压得喘不过气来。)
#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);
#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
#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('?');
}