C++中宽字符的问题
Issues with Wide Characters in C++
我有一个程序,它旨在读取单词的文本文件(每个单词都在单独的一行),然后从该文件中打印出一个随机单词。它还使您能够选择非英语语言(如希腊语或俄语)。由于后一种情况,我使用std::wstring
来捕获文本。这是代码:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/random_device.hpp>
#include <boost/random/uniform_int_distribution.hpp>
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cout << "Usage: word [lang]" << std::endl;
std::cout << "tlang: Choose from de,en,es,fr,gr,it,la,ru" << std::endl;
return EXIT_FAILURE;
}
std::string file = static_cast<std::string>("C:\util_bin\data\words_") + static_cast<std::string>(argv[1]) + static_cast<std::string>(".txt");
std::wfstream fin(file, std::wifstream::in);
std::vector<std::wstring> data;
std::wstring line;
while (std::getline(fin, line))
data.push_back(line);
int size = data.size();
boost::random::random_device rd;
boost::random::mt19937 mt(rd());
boost::random::uniform_int_distribution<int> dist(0, size - 1);
std::wcout << data[dist(mt)] << std::endl;
}
这段代码编译得很好,但当我用俄语运行它时(例如),我只得到垃圾文本:
C:util_bin>word ru
������������
C:util_bin>
我不太熟悉C++中宽字符的来龙去脉,所以我真的看不出哪里出了问题。有人有什么想法吗?
我猜您使用的是Visual Studio。这是std::basic_filebuf
在Windows中实现的一个怪癖。来自相关MSDN页面:
basic_filebuf类型的对象使用类型为
char *
的内部缓冲区创建,而与类型参数Elem
指定的char_type
无关。这意味着在将Unicode字符串(包含wchar_t
字符)写入内部缓冲区之前,它将被转换为ANSI字符串(包含char字符)。要在缓冲区中存储Unicode字符串,请创建一个类型为wchar_t
的新缓冲区,并使用basic_streambuf::pubsetbuf()
方法进行设置。
正如我所解释的,filebuf是用FILE*
实现的;有一个内部标志可以执行ANSI转换,无论您是否愿意,但无法清除。除了通过分配和设置您自己的缓冲区(通过pubsetbuf
)之外的标志。将codecvt
放在您的区域设置中是不行的。它必须在成功打开文件后立即发生。真的,令人愤怒的侵扰。我最终不得不编写一个包装类(这还不错,因为它让您能够在打开之前存储文件名)。
您也可以使用std::binary
打开该文件。有些人建议你总是这样做。但是以这种方式打开文件可能会使您在插入流或从流中提取之前进行自己的代码转换
创建实例化wfstream
对象后,对其调用imbue
,如下所示:
fin.imbue( std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>) );
- 从矢量C++读取字符时出现问题
- C++:__aligned(__alignof__) 导致字符数组数据出现问题?
- C++理解计算字符变量的问题
- 将十六进制值设置为用于填充的字符变量时出现问题
- 编写 cin.get() 以接收字符数组时出现问题
- 从 argv[1] 转换为字符 * 字符串后有什么问题?
- 将字符数组转换为结构时出现问题. 结构的字符数组变量溢出
- 字符 * 未从重载运算符或内存管理问题正确返回
- 将utf16宽std::wstring转换为utf8窄std::string以获得罕见字符时出现问题
- 我在使用字符的函数时遇到了一些问题
- 用wchar_t处理 unicode 字符好吗?它不会引起任何问题吗?
- 将 c++ 字符串转换为常量字符 * 时出现问题
- C++程序,将整数输入转换为字符的问题
- 我通过迭代加法将二进制数转换为十进制并检查单个字符(请参阅代码)的方法有什么问题?
- C++ 初级面试问题:仅使用字符指针压缩字符序列的功能
- 通过比较字符设置字符串时出现问题
- 我的编辑距离递归代码中的字符类型有问题
- 获取“boost::文件系统::p ath”字符指针时出现问题
- C Unicode UTF-8解码字符的问题
- 类型转换问题:字符数组的元素转换为整数变量