【问题标题】:what locale does wstring support?wstring 支持什么语言环境?
【发布时间】:2013-01-22 13:48:59
【问题描述】:

在我的程序中,我使用wstring 打印出我需要的文本,但它给了我随机密码(由于不同的编码方案)。例如,我有这个代码块。

wstring text;
text.append(L"Some text");

然后我使用 directX 在屏幕上渲染它。我曾经使用wchar_t,但听说它有便携性问题,所以我切换到swtringwchar_t 工作得很好,但它似乎只取了我能说的英文字符(打印输出完全忽略输入的非英文字符),这很好,直到我切换到wstring:我只有随机密码看起来像中国人和韩国人混在一起。有趣的是,我的非 unicode 文本的计算机区域设置是中文。根据我所看到的,我怀疑它会正确呈现汉字,所以我尝试了一下,它确实正确显示了字符,但前面有一个正方形(这仍然是一种不正确的显示)。然后我猜测编码可能取决于语言区域所以我将区域设置切换为英语(美国)(我使用 win8),然后我重新启动并看到源文件中的中文测试字符变成了一些随机的东西(我的文件没有保存在 unicode 格式,因为所有文本都是英文)然后我尝试使用英文字符,但没有运气,显示看起来完全一样,与语言环境无关。但我不明白为什么它不能正确显示并且看起来像亚洲字符(即使我使用英语语言环境)。

是否应该进行一些转换,或者我应该以不同的编码格式保存我的文件?问题是我想正确显示英文字符,这是默认值。

【问题讨论】:

  • 每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求:joelonsoftware.com/articles/Unicode.html
  • @Laurent 但它如何帮助我解决这个问题?
  • @ryf9059:它提供了有关这些类型问题的背景信息。

标签: c++ text character-encoding


【解决方案1】:

在没有代码说明你的问题的情况下,我会给你一个相应的一般性答案。

您正在尝试显示英文字符,但看到的是中文字符。当您将 8 位 ANSI 文本传递给接收 UTF-16 文本的 API 时,就会发生这种情况。在您的程序中寻找从char* 转换为wchar_t* 的位置。

【讨论】:

  • 问题解决了!原来是渲染,但您的信息仍然很有帮助。谢谢! :)
  • 哦...不是渲染问题,而是投射问题...只是想纠正这个问题。
  • 实际上我的回答是相当不错的猜测。好的,不是您从 ANSI 文本进行转换,而是您从一个包含对象的内存块进行转换。
【解决方案2】:

首先,您要在其中存储文本的文件类型是什么?默认情况下,普通 txt 文件存储在 ANSI 中(excel 也是如此)。因此,当您尝试将 Unicode 字符打印到 ANSI 文件时,它将打印垃圾。克服这个问题的两种方法是:

  1. 尝试以 UTF-8 或 16 模式打开文件,然后写入
  2. 在写入文件之前将 Unicode 转换为 ANSI。如果您使用的是 Windows,那么 MSDN 提供了特定的 API 来执行 Unicode 到 ANSI 的转换,反之亦然。如果您使用的是 Linux,则使用 Google 将 Unicode 转换为 ANSI。有很多解决方案。

希望对你有帮助!!!

【讨论】:

    【解决方案3】:

    std::wstring 根本没有任何语言环境/国际化支持。它只是一个存储wchar_t序列的容器。
    wchar_t 的问题在于其编码未指定。它可能是 Unicode UTF-16,或 Unicode UTF-32,或 Shift-JIS,或完全不同的东西。无法从程序中分辨出来。

    如果您确保源代码的编码与程序运行所在的语言环境所使用的编码相同,那么您将最有可能让事情正常运行。
    但是,由于第三方库期望和支持的编码可能受到限制,使用第三方库(如 DirectX)可能会带来额外的限制。

    【讨论】:

      【解决方案4】:

      Bug 解决了,原来是 CASTING 问题(不是之前说的渲染问题)。 错误文本是使用swtringstream(我忘了提)的一些内部转换过程中的中间产物,代码如下

      wstringstream wss;
      wstring text;
      textToGenerate.append(L"some text");
      wss << timer->getTime()
      text.append(wss.str());
      

      在这个过程之后,调试器将文本显示为一堆随机的东西,但后来它以某种方式转换回来,所以它是可读的。但是问题出现在使用 DirectX 的渲染阶段。我不知何故为wchar_t* 留下了铸件,导致渲染不正确。

      旧:

      LPCWSTR lpcwstrText = (LPCWSTR)textToDraw->getText(); 
      

      新:

      LPCWSTR lpcwstrText = (*textToDraw->getText()).c_str();
      

      通过改变解决问题。

      所以,这是由糟糕的演员阵容造成的。由于某些好心人对我的陈述进行了更正。

      【讨论】:

      • 这看起来根本不是渲染问题。这看起来像一个假演员。
      • 这不是渲染问题。与 MFC 字符串不同,std::(w)string不能转换为 char*/wchar_t*。这就是 c_str() 函数存在的目的。
      猜你喜欢
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多