【发布时间】:2018-04-08 14:46:43
【问题描述】:
我开了一个question有点迷茫,我想在这里说的更具体一点。
我有许多包含德语字母的文件,大部分采用 iso-8859-15 或 UTF-8 编码。为了处理它们,必须将所有字母转换为小写。
例如,我有一个文件(编码为 iso-8859-15 ),其中包含:
博士。玫瑰在 M. Das sogen。 Baptisterium zu Winland, eins der im Art。 "Baukunst" (S. 496) erwähnten Rundgebäude in Grönland, soll nach Palfreys “新英格兰历史” eine von dem Gouverneur Arnold um 1670 erbaute Windmühle sein。 Vgl。阵风。书房里的风暴“Jahrbüchern der” 哥本哈根 königlichen Gesellschaft für nordische Altertumskunde" 1887 年,S. 296。
Ää Öö Üü ẞß Örebro
文本Ää Öö Üü ẞß Ö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
env中启用或安装de_DE语言环境才能正确处理字符串的字符? - 以同样的方式处理
std::string这样的文本是否安全 从具有不同编码(iso-8859-15 或 UTF-8)的文件中提取?
编辑:康拉德鲁道夫的回答仅适用于 UTF-8 文件。它不适用于 iso-8859-15,这会转化为此处发布的初始问题: How to apply functions on text files with different encoding in c++
【问题讨论】:
-
有些字母不能没有小写表示。有些可以但不往返。
-
我非常幸运地制作了自己的翻译表。如果我是你,我会将 ISO 8859-15 翻译成 Unicode。在您的代码中,您似乎尝试以各种排列方式使用 ISO 8859-1。 ISO 8859-15 不是 ISO 8859-1。
-
@RichardCritten 我提到的那些都是大写的吗?
-
您的系统上可能未正确设置区域设置。您应该尝试以下问题的解决方案:stackoverflow.com/questions/19100708
-
C++ 在编码方面是一种标准的平底船。
std::locale受操作系统提供的支配,而且(在我看来)有点笨拙。我尝试坚持使用 Unicode;大部分是 UTF-8,有时是 WTF-8、UTF-16 或 UTF-32,但我会尽快转换为 UTF-8。任何其他编码我也会尽可能靠近边缘翻译成 Unicode (UTF-8)。我在使用 IBM 的 ICU 时有很好的经验。而且,我承认,有时我使用 Python 3.x 将数据预先整理成 Unicode。
标签: c++ stl character-encoding