问题描述
我想在Ubuntu 20.04上读取文件txt编码的UTF8。
我在wcout cout和ifstream中添加了语言环境fr_FR.UTF-8。
我当时想添加语言环境就足够了。
这是我的代码
...
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <string>
#include <locale>
#include <codecvt>
int main(int argc,char** argv){
int nbreLigne;
std::vector<std::wstring> dico;
std::string path("liste_test.txt");
std::wstring ligne;
std::locale loc("fr_FR.UTF-8");
std::cout.imbue(loc);
std::wcout.imbue(loc);
std::wifstream file(path.c_str(),std::ios::in);
file.imbue(loc);
std::cout << "Path = " << path << std::endl;
std::cout << "1- locale wifstream : " << file.getloc().name() << std::endl;
std::cout << "2- locale wcout : " << std::wcout.getloc().name() << std::endl;
std::cout << "3- locale cout : " << std::cout.getloc().name() << std::endl;
/* Pas d'erreur de compile mais ne semble pas avoir d'effet
file.imbue(std::locale(file.getloc(),new std::codecvt_utf8<wchar_t,0x10ffff,std::consume_header>));
std::cout << "1- Variable de localisation : " << file.getloc().name();
*/
if (file){
//compte les lignes
while (std::getline(file,ligne)){
nbreLigne++;
dico.push_back(ligne);
/*
Erreur de segmentation (core dumped) si cette ligne est activée
std::wcout << dico[nbreLigne] << std::endl;
*/
}
std::cout << "Total lines number = " << nbreLigne << std::endl;
}
else{
std::cout << "ERREUR: Impossible d'ouvrir le fichier." << std::endl;
}
std::cout << "-------------------" << std::endl;
std::cout << "Lecture de la variable dico" << std::endl;
std::cout << std::endl;
for(int i = 0; i < nbreLigne; i++){
std::wcout << dico[i] << std::endl;
}
...
如何在cout,wcout和ifstream中正确使用语言环境?
解决方法
为简单回答,没有通用的方法来处理C ++和大多数编程语言中的重音字符。仅ASCII是几乎通用的,并且仅覆盖英文字符。随着时间的流逝,从Windows code page到UTF-8到wide-char的低谷诞生了多种处理语言特定字符的解决方案( 您的问题不是您的程序(除非在这种情况下,它仅应使用 解决字符集问题既困难又无聊。对于您而言,以UTF-8或使用 此外,在C ++流上设置语言环境仅会更改std::wcout
适用于宽字符)。
std::cout
),而是您的词典使用的字符集与终端的字符集不同。iconv(1)
手工重写字典是值得的。在实际的项目中,您将使用GNU gettext之类的国际化(i18n)工具来为您处理此负担。今天,大多数现代系统都使用UTF-8。<<
浮点数时程序格式值(如小数点分隔符)的方式,它无法更改控制台语言环境,因为std::cin
不一定是终端而且可能很奇怪。