为什么towlower()函数不将Я转换为小写的字符?
Why does the towlower() function not convert the Я to a lower-case я?
函数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;
}
字符保持大写。以前这里也有人问过类似的问题,但我找不到任何解决办法。
是否有其他方法可以将其改为小写?
使用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中使用区域设置是一件棘手的事情,这背后隐藏着一个完整的潘多拉魔盒。例如,你可以用一个语言环境注入流,你可以一次管理多个语言环境,特别是你可以每个线程有一个(这可能是有状态字符串编码转换所必需的)…应该有人写一本关于这个的书(或者使用Boost.Locale)。
我认为有两种可能性。第一个是locale设置不正确。从MSDN:
towlower
的大小写转换与语言环境有关。只有与当前相关的字符区域设置在情况下会改变。没有_l
后缀的函数使用当前设置的区域设置。
第二个是源文件编码。L'Я'
可能意味着不同的东西,这取决于源文件的编码方式。它不会工作,例如,如果你有它在UTF-8
。确保你把它放在UTF-16
。或者为了消除任何可能的混淆,像这样写'u042F'
更新:在第二个想法,整个L
业务是棘手的。如果编译器正确地理解编码,例如通过BOM,那么使用UTF-8
或任何其他编码都可以。重要的是,它应该知道编码是什么。它必须是非常具体的实现。
另一个更新:要解决这个问题,请尝试通过:
设置区域设置_wsetlocale(LC_ALL, L"ru-RU");
或者使用将区域设置作为参数的版本(_towlower_l
)。
上面还有一个pragma,告诉编译器如何处理文件中的非ascii字符串。
它造成的伤害比更高吗?j/k。我不熟悉反转的R,但我知道如果字符没有对应的小写字母,to(w)lower将返回原始字符。http://en.cppreference.com/w/c/string/wide/towlower
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试将字符串/字符转换为整数会产生意外结果
- 如何使用C++将字符串中的字符转换为整数变量
- 字符转换功能 std::isupper() & std::islower() C++17
- 将字符 * 转换为字符串 *
- 在编译时将常量字符* 转换为常量 char_type*
- 如何在 C/C++ 中将无符号字符*转换为无符号字符数组?
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 无法使用字符串流将字符转换为字符串C++
- 将无符号字符 C++ 转换为 C#
- C++:使用没有位移位的指针将无符号字符转换为无符号 int
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- 无法<string>从"常量字符 []"转换为<类名>
- 不能将字符转换为整数吗?
- 编译时将字符*转换为字节
- CP1251:从字符* 转换为 wchar_t* 时的编码失真
- 将单个字符转换为 std::string 前缀 \x01
- PPM 将字符转换为 int 授予负数
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类
- 将常量字符* 转换为字符时出错