【问题标题】:Conversion between wchar_t char in ANSI Code PageANSI 代码页中 wchar_t char 之间的转换
【发布时间】:2025-12-16 13:40:02
【问题描述】:

如果我在仅 ANSI 代码页环境中。

此转换是否将wide char 转换为char

char ansi_cstr[size_of_ansi_str];
WideCharToMultiByte(CP_ACP, 0, ansi_wstr.c_str(), -1, ansi_str, size_of_ansi_str, 0, 0);
std::string ansi_str = std::string(ansi_cstr);

等于跟随

std::string ansi_str = std::string(ansi_wstr.begin(), ansi_wstr.end());

charwide char

wchar_t ansi_wcstr[size_of_ansi_str];
MultiByteToWideChar(CP_ACP, 0, ansi_str.c_str(), -1, ansi_wcstr, size_of_ansi_str);
std::wstring ansi_wstr = std::wstring(ansi_wcstr);

等于

std::wstring ansi_wstr = std::wstring(ansi_str.begin(), ansi_str.end());

这两种情况在仅 ansi 代码页的环境中是否保持相同的行为?

【问题讨论】:

  • 真正的问题是为什么你会在 2014 年使用 ANSI 代码页?
  • 更糟糕的是:ANSI 代码页 only 环境。我认为第一个支持 Unicode(通过 Unicows)的 Windows 是 Windows 95,所以这将是 1994 年的 Windows 3.1。20 岁。谈论遗留开发。话又说回来,我们仍然在这里看到 Turbo C++ 问题。
  • Windows 95/98/ME 是基于 Ansi 的操作系统。 UCS-2 在 NT4 中使用,然后在 Windows 2000 中被 UTF-16 取代。这两个产品线直到 XP 才合并为一个单一的 Unicode 操作系统。
  • @CodyGray 也许是因为,即使在 2018 年,很多 shapefile 的 DBF 仍然使用 0x57 语言驱动程序 ID?

标签: c++ unicode char wchar


【解决方案1】:

没有像 ANSI 代码页环境这样的东西。有几十个。

您的两个“快捷方式”转换均不正确。

ASCII char 到 UTF-16 wchar_t 的转换将适用于您的最后一种方法,但对于大多数 ANSI 代码页的后半部分,这将失败。它最适用于西欧代码页,其中只有 32 个字符错误。例如。欧元符号 € 总是会被错误转换。

【讨论】:

    【解决方案2】:

    WideCharToMultiByte(CP_ACP, 0, ansi_wstr.c_str(), -1, ansi_str, size_of_ansi_str, 0, 0);

    相同

    std::string ansi_str = std::string(ansi_wstr.begin(), ansi_wstr.end());

    WideCharToMultiByte() 使用CP_ACP 在该 PC 上引用的代码页执行从 UTF-16 到 ANSI 的实际转换(根据用户区域设置,每台 PC 上的代码页可能不同)。 std::string(begin, end) 只是循环遍历源容器,将每个元素类型转换为 char,根本不执行任何代码页转换。

    同样:

    MultiByteToWideChar(CP_ACP, 0, ansi_str.c_str(), -1, ansi_wcstr, size_of_ansi_str);

    相同

    std::wstring ansi_wstr = std::wstring(ansi_str.begin(), ansi_str.end());

    出于同样的原因。 MultiByteToWideChar() 使用 CP_ACP 代码页执行从 ANSI 到 UTF-16 的真正转换,而 std::wstring(begin, end) 只是将源元素类型转换为 wchar_t,根本没有任何转换。

    仅当源字符串使用 0x00-0x7F 范围内的 ASCII 字符时,类型转换才等效到 API 转换。但如果他们使用的是非 ASCII 字符,那么所有的赌注都会被取消。

    【讨论】: