VC++中用于Unicode字符串的语法是什么?

5

在VC++中如何使用Unicode字符串呢?当然,你应该定义#define UNICODE,但是对于你的字符串来说呢?

是否应该在所有的文本周围使用TEXT()或_T()宏,还是只要在字符串前面加上L即可?我相信现在所有程序都应该使用Unicode,所以使用L前缀会更清晰吧。

你有什么看法呢?


1
为了可移植性和可读性,我强烈不建议使用微软的魔法T-字符串,而是应该使用宽字符串。 - Kerrek SB
2
@Axel,请告诉我如何调用UTF-8版本的GetWindowText函数? - David Heffernan
3
除了Win32 API不接受UTF-8,这在某种程度上限制了可移植性。 wchar_tint 的可移植性相同。它不能保证在所有平台上的大小相同,并且其内部表示可能不同,但是使用该类型来存储所需内容的源代码将在所有平台上运行。对于跨平台代码,您仍然需要处理编码转换,因此我不认为utf8更好。 - jalf
@KerrekSB:你是否真的在意 _T 是微软特有的? tchar.h 看起来与其他任何东西都没有太大关系,可以在任何平台上使用而几乎不需要更改。而且你总是可以重新定义 _T 以使用 UTF-8 或其他编码方式,所以我不明白为什么要删除它会有什么问题... - user541686
@Mehrdad:如果你认真采用微软的方法,你几乎会使用所有C标准库函数的T_t版本,以及_tmain()。因此……可移植性会受到严重影响。 - Kerrek SB
显示剩余3条评论
3个回答

2

这取决于您想要实现什么目标。如果您希望确保您的代码可以在Unicode和非Unicode环境下编译和正常工作,可以使用TEXT_T宏,并调用“默认”的Win32函数名称(例如CreateWindow)。

如果您希望确保您的程序始终使用Unicode API,则应在字符串前面使用L前缀,并调用Win32函数的广义版本(例如CreateWindowW)。

后一种情况下,无论是否定义了UNICODE,都会获得Unicode行为。 在前一种情况下,您的应用程序将根据是否定义了UNICODE而更改其行为。

我同意您的观点,自Win98以来,非Unicode版本实际上已经不再相关,所以我建议采用第二种方法。


1
如果您要使用Unicode而不支持ANSI,则为了可读性,最好使用CreateWindow - David Heffernan
1
无论是否定义了UNICODE,您的代码可能已经出现了问题。我没有看到任何真正的额外安全性,只有视觉上的混乱。 - David Heffernan
1
@jalf:如果编译器设置错误,代码无法编译通过我完全没问题。为了可读性,我会使用CreateWindow(L"HI");,它将使用Unicode,或者提醒我忘记设置UNICODE定义。 - Mooing Duck
2
@MooingDuck:你绝对不应该说CreateWindow(L"HI")——这是两者最糟糕的结合!它既没有兼容性,也没有可移植性。要么使用CreateWindow(_T("HI")),要么使用CreateWindowW(L"HI"),但不要混用。 - user541686
CreateWindow(L"HI") 绝对是你从 ANSI 中脱离后应该写的东西。 - David Heffernan
显示剩余7条评论

1

使用L前缀声明Unicode字符串字面值。

TEXT()_T()宏是为了早期需要单一源代码同时编译Unicode和非Unicode版本的Windows(Windows 9x)。如今可以放心地忽略Windows 9x。


1

我之前学到的一些东西:

黄金法则:

不要与框架对抗。

做框架设计的事情 - 如果你使用Windows,使用_T,使你的代码独立于字符类型。如果你在Linux上,使用UTF-8。如果你有一个跨平台的框架,就按照它的方式去做。但是,除非你有一个非常好的理由,否则不要试图发明自己的东西。(通常来说,与框架对抗的努力往往是不值得的。)


1
@David:在Kyle的情况下,他正在编写使用_T宏的Windows API框架。你正在使用哪个框架进行编码? - Mooing Duck
为了论证,我正在编写适用于Windows API的代码,不需要使用“_T”或“TEXT”宏。 - David Heffernan
@DavidHeffernan:它并不需要它们,但是它是设计用于与它们一起使用的。所以,与其与之对抗,不如顺应它。 - user541686
@Mehrdad 它并不是为了与它们一起使用而设计的。它们被提供是为了简化单一源代码的开发,以便能够同时针对 ANSI 和 Unicode 进行目标开发。如果你只针对 Unicode 进行开发,就像问题所描述的那样,那么它们是不必要的。 - David Heffernan
为什么我要使用MBCS进行任何操作?我只想针对Unicode API,就像问题中所提到的一样。 - David Heffernan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接