加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

如何在C中正确应用tolower()德语大写字母?,?,ü,?

发布时间:2020-12-16 07:22:57 所属栏目:百科 来源:网络整理
导读:我有点困惑,因为我已经开了一个 question,我想在这里更具体一点. 我有很多文件包含德语字母,大部分是iso-8859-15或UTF-8编码.为了处理它们,必须将所有字母转换为小写. 例如,我有一个文件(编码在iso-8859-15中),其中包含: Dr. Rose in M. Das sogen. Baptist
我有点困惑,因为我已经开了一个 question,我想在这里更具体一点.

我有很多文件包含德语字母,大部分是iso-8859-15或UTF-8编码.为了处理它们,必须将所有字母转换为小写.

例如,我有一个文件(编码在iso-8859-15中),其中包含:

Dr. Rose in M. Das sogen. Baptisterium zu Winland,eins der im Art.
“Baukunst” (S. 496) erw?hnten Rundgeb?ude in Gr?nland,soll nach
Palfreys “History of New England” eine von dem Gouverneur Arnold um
1670 erbaute Windmühle sein. Vgl. Gust. Storm in den “Jahrbüchern der
k?niglichen Gesellschaft für nordische Altertumskunde in Kopenhagen”
1887,S. 296.

?? ?? üü ?? ?rebro

文本应该成为:????üü???rebro.

但是,tolower()似乎不适用于大写字母,例如?,?,ü,?,尽管我尝试强制使用this SO post中提到的语言环境

这是与我在其他问题中发布的代码相同的代码:

std::vector<std::string> tokens;
std::string filename = "10223-8.txt";
//std::string filename = "test-UTF8.txt";
std::ifstream inFile;

//std::setlocale(LC_ALL,"en_US.iso88591");
//std::setlocale(LC_ALL,"de_DE.iso88591");
//std::setlocale(LC_ALL,"en_US.iso88591");
//std::locale::global(std::locale(""));

inFile.open(filename);
if (!inFile) { std::cerr << "Failed to open file" << std::endl; exit(1); }

std::string s = "";
std::string line;
while( (inFile.good()) && std::getline(inFile,line) ) {
    s.append(line + "n");
}
inFile.close();

std::cout << s << std::endl;

//std::setlocale(LC_ALL,"de_DE.iso88591");
for (unsigned int i = 0; i < s.length(); ++i) {
    if (std::ispunct(s[i]) || std::isdigit(s[i]))
            s[i] = ' ';
    if (std::isupper(s[i]))
            s[i] = std::tolower(s[i]);
            //s[i] = std::tolower(s[i]);
            //s[i] = std::tolower(s[i],std::locale("de_DE.utf8"))
}

std::cout << s << std::endl;

//tokenize string
std::istringstream iss(s);
tokens.clear();
tokens = {std::istream_iterator<std::string>{iss},std::istream_iterator<std::string>{}};

//PROCESS TOKENS...

它真的很令人沮丧,并且关于< locale>的使用的范例并不多.

因此,除了我的代码的主要问题,这里有一些问题:

>我是否也必须在其他函数中应用某种自定义语言环境(isupper(),ispunct()…)?
>我是否需要在我的linux环境中启用或安装de_DE语言环境才能正确处理字符串的字符?
>以与std :: string相同的方式处理文本是否安全
从具有不同编码的文件中提取(iso-8859-15或UTF-8)?

编辑:Konrad Rudolph答案仅适用于UTF-8文件.它不适用于iso-8859-15,它转换为此处发布的初始问题:
How to apply functions on text files with different encoding in c++

解决方法

使用 std::ctype::tolower,而不是std :: tolower:

#include <iostream>
#include <locale>

int main() {
    std::locale::global(std::locale("de_DE.UTF-8"));
    std::wcout.imbue(std::locale());
    auto& f = std::use_facet<std::ctype<wchar_t>>(std::locale());
    std::wstring str = L"?? ?? üü ?? ?rebro";
    f.tolower(&str[0],&str[0] + str.size());
    std::wcout << "'" << str << "'n";
}

您可以创建本地区域设置(heh),而不是设置全局区域设置:

std::locale loc("de_DE.UTF-8");
std::wcout.imbue(loc);
auto& f = std::use_facet<std::ctype<wchar_t>>(loc);

这编译和“工作”.在我的系统上,它正确地转换了变音符号,但它无法处理首都 – ?(不出所料,说实话).

此外,请注意此功能的限制:它只能执行1对1的字符转换.在以前版本的Unicode标准中,“?”的正确大写转换是“SS”. std :: ctype :: toupper显然从不支持这个.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读