澄清Winapi路径和文件名(W函数和A函数)

时间:2018-03-19 15:56:58

标签: c windows winapi unicode ascii

我试图检查使用W winapi vs A的重要性和理由,(W表示宽字符,A表示ascii对吗?)

我做了一个简单的例子,我收到了当前用户的临时路径,如下所示:

CHAR pszUserTempPathA[MAX_PATH] = { 0 };
WCHAR pwszUserTempPathW[MAX_PATH] = { 0 };

GetTempPathA(MAX_PATH - 1, pszUserTempPathA);

GetTempPathW(MAX_PATH - 1, pwszUserTempPathW);

printf("pathA=%s\r\npathW=%ws\r\n",pszUserTempPathA,pwszUserTempPathW);

我当前的用户有一个俄语名称,所以用西里尔语写的printf输出如下:

pathA=C:\users\Пыщь\Local\Temp
pathW=C:\users\Пыщь\Local\Temp

所以两条路径都没问题,我认为我会收到一些错误,或者是一堆GetTempPathA的符号,因为当前用户是unicode,但我发现,西里尔字符实际上包含在扩展名中ascii字符集。所以我有一个问题,如果我要使用我的软件,它将在当前用户的临时文件夹中提取数据,这是中文(假设他在用户名中有中文符号),我会弄得一团糟或使用错误GetTempPathA版本?对于直接使用winapi的生产软件,我是否总是使用W前缀函数?

2 个答案:

答案 0 :(得分:6)

首先,-A后缀代表ANSI,而不是ASCII。 ASCII是一个7位字符集。 ANSI使用该术语,用于使用8位代码单元(char s)和代码页进行编码。

有些人使用术语“扩展ASCII”或“高位ASCII”,但这实际上并不是标准,在某些情况下,与ANSI不完全相同。扩展ASCII是ASCII字符集加上(最多)128个附加字符。对于许多ANSI代码页,这与扩展ASCII相同,但是一些代码页适用于可变长度字符(Microsoft称为多字节)。有些人认为“扩展ASCII”只是指ISO-Latin-1(几乎与Windows-1252相同)。

无论如何,使用ANSI函数,您的字符串可以包含当前代码页中的任何字符。 如果您需要不属于当前代码页的字符,那么您将失去运气。您必须使用宽-W版本。

在现代版本的Windows中,通常可以将-A函数视为-W函数的包装器,这些函数使用MultiByteToWideChar和/或WideCharToMultiByte来转换通过API的任何字符串。但后一种转换可能是有损的,因为宽字符串可能包含多字节字符串无法表示的字符。

便携式跨平台代码通常存储all text in UTF-8,它使用8位代码单元(char s),但可以表示任何Unicode代码点,并且随时需要通过Windows API文本,你明确地转换为/从宽字符转换,然后调用-W版本的API。

UTF-8几乎与Microsoft称为多字节ANSI代码页的类似,只是Windows不完全支持UTF-8代码页。有CP_UTF8,但它只适用于某些API(如WideCharToMultiByte和MultiByteToWideChar)。您无法将代码页设置为CP_UTF8,并希望通用-A API能够做正确的事情。

当您尝试测试时,请注意,让CMD控制台窗口显示当前代码页之外的字符很困难(有时甚至是不可能的)。如果要显示多脚本字符串,您可能应该编写GUI应用程序和/或使用调试器来检查字符串的实际内容。

答案 1 :(得分:-2)

当然,你需要宽版本。 ASCII版本甚至不能在技术上处理超过256个不同的字符。西里尔文包含在扩展的ASCII集中(如果这是您的本地化),而中文则不是,也不能由于代表它需要更大的字符集。此外,你也可以搞乱西里尔语 - 它只有在执行机器具有匹配的本地化时才能正常工作。因此,在具有非西里尔文本地化的计算机上,将根据本地化设置定义的内容显示文本。