【问题标题】:Why does the towlower() function not convert the Я to a lower-case я?为什么 towlower() 函数不能将 Я 转换为小写 я?
【发布时间】:2013-03-31 03:58:26
【问题描述】:

towlower() 函数似乎在 Visual Studio 2012 中不起作用。下面是一个示例:

#include <string>
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <wctype.h>

using namespace std;

int main()
{
    _setmode(_fileno(stdout), _O_U8TEXT);
    wcout << (wchar_t)towlower(L'Я') << endl;
    system("pause");
    return 0;
}

字符保持大写。以前在这里问过类似的问题,但我找不到任何解决方案。

我可以使用其他方法更改为小写吗?

【问题讨论】:

  • We close all typo questions, 顺便说一句。
  • 什么意思?没有错字。
  • 您需要手动设置语言环境,因为 C++ 默认使用不变的 C 语言环境,无论如何。不过,我不知道 Windows 上安装了哪些 Unicode 语言环境。
  • @jalf:你不觉得“过于本地化”只是一个双关语吗?
  • @CodyGray 平台很重要。例如,语言环境在不同的平台上有不同的名称,这是一个相关的细节。

标签: c++ unicode locale lowercase wchar-t


【解决方案1】:

我看到了两种可能性。第一个是语言环境设置不正确。来自MSDN

towlower 的大小写转换是特定于语言环境的。只有与当前相关的字符 以防万一更改语言环境。没有_l 后缀的函数使用当前设置的语言环境。

第二个是源文件编码。 L'Я' 可能意味着不同的东西,具体取决于您的源文件的编码方式。例如,如果您在 UTF-8 中拥有它,它将无法工作。确保你有它在UTF-16。或者为了消除任何可能的混淆,像这样'\u042F'

更新:转念一想,整个L 业务很棘手。如果编译器可以正确理解编码,例如通过 BOM,则可以使用 UTF-8 或任何其他编码。重要的是它应该知道编码是什么。它必须是非常具体的实现。

另一个更新:要解决此问题,请尝试通过以下方式设置区域设置:

_wsetlocale(LC_ALL, L"ru-RU");

或使用将语言环境作为参数的版本 (_towlower_l)。

还有一个pragma 告诉编译器如何处理文件中的非ASCII 字符串文字。

【讨论】:

  • 默认情况下,我相信 VC++ 将源文件视为 Windows-1252 编码(也称为几乎但不完全是拉丁语 1),这意味着像 Я 这样的花哨字符可能会被破坏。所以,是的,绝对使用\u042f。 :)
  • VC++ 可以识别 Unicode BOM 并采取相应措施,即使在 UTF-8 文件中也是如此。
【解决方案2】:

使用tolower 的语言环境感知版本,但不要忘记同时设置C 语言环境。

例如:

#include <clocale>
#include <locale>
#include <iostream>

int main()
{
    std::setlocale(LC_CTYPE, "");
    std::wcout << L"The letter is: " << L'Я' << L" => "
               << std::tolower(L'Я', std::locale("")) << std::endl;
}

打印出来:

The letter is: Я => я

在 iostreams 中使用语言环境是一件棘手的事情,而这背后隐藏着一个完整的潘多拉魔盒。例如,您可以imbue 使用区域设置流,并且可以一次管理多个区域设置,特别是每个线程可以有一个(这可能是有状态字符串编码转换所必需的)...有人应该为此写一本书(或者改用 Boost.Locale)。

【讨论】:

    【解决方案3】:

    它造成的伤害是否比更高的更少? j/k。我不熟悉反转的 R,但我知道如果字符没有等效的小写字母,to(w)lower 将返回原始字符。 http://en.cppreference.com/w/c/string/wide/towlower

    【讨论】:

      猜你喜欢
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2016-08-07
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      相关资源
      最近更新 更多