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('?');
}