C++ 字符串小写与自定义语言环境

C++ String to lowercase with custom locale

我一直在尝试使用不同的区域设置调用 std::tolower(),但似乎出了点问题。我的代码如下:

int main() {
    std::locale::global(std::locale("es_ES.UTF-8"));
    std::thread(&function, this); // Repeated some times
    // wait for threads
}

void function() {
    std::string word = "HeÉllO";
    std::transform(word.begin(), word.end(), word.begin(), cToLower);
}

int cToLower(int c) {
    return std::tolower(c, std::locale());
}

所以当我尝试执行这个程序时,我得到:

terminate called after throwing an instance of 'std::bad_cast'
terminate called recursively
  what():  std::bad_cast
Aborted (core dumped)

虽然执行 return std::tolower(c); 工作正常,但它只是将 'standard' 字符转换为小写,而不是 É.

我有一些线程同时执行相同的功能,使用 C++11 并用 g++ 编译(以防它与它有关)。

我想知道这是实现我想做的事情的正确方法,还是有其他方法。

谢谢!

检查您尝试使用的语言环境是否安装在您的系统上。例如,我必须在下面的代码停止崩溃之前安装西班牙语语言环境。 此外,您可以使用 wstring 代替。 更新:经过一些挖掘 here 是对使用 wstring 的很好解释 - 所有缺点和过程(主要是缺点)。

#include <thread>
#include <locale>
#include <algorithm> 
#include <iostream>

//forward declaration
void function();

int main() {
    std::locale::global(std::locale("es_ES.utf8"));
    std::thread test(&function);
    test.join();
}

wchar_t cToLower(wchar_t c) {        
    return std::tolower(c, std::locale());    
}

void function() {
    std::wstring word = L"HeÉllO";
    std::transform(word.begin(), word.end(), word.begin(), cToLower);
    std::wcout << word;
}

输出:

heéllo

不同于来自 C 的 tolower 版本(将字符转换为 unsigned char,然后再转换为 int),<locale> 版本的 tolower 意味着直接用字符调用。它被定义为使用语言环境的 std::ctype<charT> 方面,并且仅有的两个 std::ctype 特化 guaranteed to be availablestd::ctype<char>std::ctype<wchar_t>。因此:

char cToLower(char c) {
    return std::tolower(c, std::locale());
}

请注意,这仍然是一个 char-by-char 变换;如果字符占用超过一个字节,则不太可能正确处理。