【问题标题】:TCHAR, WCHAR, LPWSTR, LPSTR, wstring clarificationTCHAR、WCHAR、LPWSTR、LPSTR、wstring 说明
【发布时间】:2014-12-21 11:11:30
【问题描述】:

大家好,下午好。所以我对这个场景仍然很陌生,但对它有很大的野心,我一直在努力学习。我认为自己擅长 C++,但我一直在编写 DOS 程序,最近我将视野扩大到 Windows API....话虽如此,我注意到 Windows API 与 UNI 密切相关- CODE 而 DOS 使用 ANSI.. 所以我知道 ANSI 使用 8 位字符代码而 UNI-CODE 使用 16 位.. 所以我的问题是:

1) 为什么这很重要.. 由于它的 16 位与 8 相比,它是否更具体或能够保存更多信息?我的意思是我知道有些字符 ANSI 不支持 UNI-CODE 支持但是这样吗?

2) TCHAR 和 WCHAR 之间有什么区别,它只是 char 的 16 位版本吗?如果 WCHAR 是宽字符,那么 TCHAR 是什么?

3) 我知道 LPWSTR 是指向宽字符串的长指针,但你什么时候使用它,为什么?它只是一个窗户的东西吗?长指针不是自动16位吗?这是否意味着常规指针是 8 位?如果是这样,你为什么需要额外的位?

4)接下来为什么需要 wstring 以及是否需要将 wchar 和 tchar 与它一起用于某些功能?即

wstring myStr;
TCHAR myChar;
if (myStr.find(myChar) != string::npos) { krmormrm }

或者这有关系吗..

char myChar;
if (myStr.find(myChar) != string::npos) { jnrnikvnr }

5) 最后但并非最不重要的一点是,我无法在没有转换的情况下显示 WCHAR 和 wstring 甚至 int。例如(我想通了)我做到了:

WCHAR myChar = '1';
int i = 2;
wstring myString;

ofstream File1("myFile.txt");

if (File1.is_open())
{
    File1 << (char)myChar; //if i didn't typecast it to char it displayed 49 instead of 1;
    File1 << (WCHAR)i; //if i didn't typecast it to WCHAR(like to char instead)it displays symbols

    WCHAR temp;
    copy(myString.begin(), myString.end(), temp);

    File1 << (char)temp;
}

好的,所以我对 wstring 和副本有一点问题。我在我的真实程序中所做的(这只是一个快速的脚本)使用了 9 个 WCHAR 变量...使用 wstringstream 将它们全部加载到它的变量(wss)中,然后加载到 myString(我的 wstring 变量)...所以为了确保它们都正确加载,我将其复制到 WCHAR 临时文件中以将其发送到 file1,这样我就可以实际看到加载到其中的内容,但由于某种原因,它加载了我想要的变量以及我不想要的额外变量,我多次检查代码并没有发现任何问题..所以我摆脱了复制功能并使用 for 循环单独显示每个变量,例如:

for (int i = 0; i < 81; i++)
{
    File1 << "Box " << (WCHAR)i << ": " << (char)BoxNum[i] << "\n";
}

我得出的结论是所有内容都包含正确的值...只是仅供参考,我将值输入到文本框中并检索文本并将其存储在各个变量中..文本框按 9 x 9 排列...所以一行有 9 个,一列有 9 个……然后我使用第一行框中的变量并将其放入 myString 中,这样我就可以使用 string.find() 函数来检查该行中的数字而不是逐个框..我的问题是显示这个wstring......无论如何,抱歉只是试图提供尽可能多的信息,也许有人也可以为我解决这个问题。

【问题讨论】:

  • 这不是一个问题,而是很多问题。这种多点问题不适合 stackexchange,因为不能回答每一个问题的人不鼓励回答,因为他们的答案会因为不完整而被否决。最好分别询问每个子问题。
  • 好的,抱歉。我没有考虑这个..
  • 当您尝试创建一个宽字符串常量时,您应该使用另一种语法:L"a string"(引号前的字母 L)。这并不能回答您的所有问题,但可能会有所帮助。
  • 10 年前,当最后一个软盘驱动器在最后一台维护的 Windows 98 机器上死机时,这一切都不再相关了。世界是 Unicode,你的操作系统也是,只有 WCHAR[](又名 wchar_t[])和 LPWSTR(又名 wchar_t*)仍然重要。

标签: c++ windows wstring wchar


【解决方案1】:
  1. 8 位字符编码只允许 256 个不同的字符,减去很多控制字符。这对英语来说已经足够了,但是当你想覆盖其他欧洲语言时,比如那些包含 ößéø 等奇怪字符的语言,这根本不够。当然,您可以使用不同的代码页,在 8 位编码的较高 128 个代码点上放置不同的字符,但是如果您需要在同一个字符串中混合多种语言怎么办?那么像中文这样的超过 256 个字符的语言呢?但是对于每个字符 16 位,您可以使用超过 60.000 个代码点,这足以在单个代码页中覆盖整个 basic multilingual plane

  2. WCHAR 始终为 16 位。 TCHAR 可以是 8 位或 16 位,具体取决于您是否将程序编译为 unicode 程序。

  3. 长指针和短指针之间的区别主要是历史性的,在现代平台上并不太关心(如果你真的想知道,请查看this question)。 Windows API 有很长的历史可以追溯到第一个 Windows 版本,所以你会发现那里有很多过时的东西。指针的长度取决于程序的种类。 32 位程序有 32 位长指针,64 位程序有 64 位长指针。当您为 64 位编译程序时,LPWSTR 将是一个 64 位指针(指向一个以空字符结尾的 16 位字符数组)。

  4. 第一个代码仅在 TCHAR 为 16 位时才有效,因为在这种情况下 WCHAR 和 TCHAR 是一回事。当 TCHAR 为 8 位时,该代码将无法编译,因为查找方法需要与创建字符串的类型相同。

  5. 当您将 16 位字符串写入文件时,它会作为 16 位字符串写入文件。当您随后使用文本编辑器打开它并且只看到垃圾时,这可能是因为您的文本编辑器使用 8 位字符编码来解释它。将文本编辑器的编码切换为您编写文件时使用的编码(UTF-16 可能有效)。或者在编写之前将wstring 转换为string,如this question 中所述。但请记住,当您的字符串中存在无法用 8 位表示的字符时,这将无法正常工作。

【讨论】:

  • 好答案。关于答案二,我很确定 TCHAR 是 Windows 的东西。我不知道其他平台使用它。而在使用TCHAR 时选择CHARWCHAR 的东西是如果定义了_UNICODEUNICODE
  • 谢谢!所以只有一件事我不清楚。当我使用 File1 &lt;&lt; (char)i;(int)i 发送到 File1 时,它会显示符号,但是通过将类型转换更改为 WCHAR 它会在被视为 16 位的同时正确显示,但是使用实际的 WCHAR 变量,我必须将其类型转换为 char ,这会将其视为 8 个字节。如果不进行类型转换,它显示为 49 而不是 1。这是因为 UNI CODE 和 ANSI 或文本编辑器中的字符定位吗?
  • @PrErkle 确实如此。字符 1 的 ASCII 值为 49,因此当您将整数 49 写入文件(通过将其转换为 char 将其从 32 位截断为 8 位)然后用文本编辑器打开它时,您会得到字符 @ 987654340@.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2018-12-31
相关资源
最近更新 更多