我必须首先用西里尔文读取一个文件,然后随机选择随机数行并将修改后的文本写入另一个文件。拉丁字母没有问题,但我遇到了西里尔文的问题,因为我得到了一些垃圾。所以这就是我试图做的事情。
说,文件input.txt
是
ааааааа
ббббббб
ввввввв
我必须阅读它,并将每一行放入一个向量中:
vector<wstring> inputVector;
wstring inputString, result;
wifstream inputStream;
inputStream.open("input.txt");
while(!inputStream.eof())
{
getline(inputStream, inputString);
inputVector.push_back(inputString);
}
inputStream.close();
srand(time(NULL));
int numLines = rand() % inputVector.size();
for(int i = 0; i < numLines; i++)
{
int randomLine = rand() % inputVector.size();
result += inputVector[randomLine];
}
wofstream resultStream;
resultStream.open("result.txt");
resultStream << result;
resultStream.close();
那么我怎样才能与西里尔语合作,以便产生可读的东西,而不仅仅是符号?
答案 0 :(得分:2)
因为您看到类似■aaaaaaa 1♦1♦1♦1♦1♦1♦1♦2♦2♦2♦2♦2♦2♦2♦打印到控制台,看起来{{1} }以UTF-16编码编码,可能是UTF-16 LE + BOM。如果将文件的编码更改为UTF-8,则可以使用原始代码。
使用UTF-8的原因是,无论文件流的char类型如何,input.txt
的基础basic_fstream
都使用basic_filebuf
对象来转换{ {1}}来自/来自char类型的对象流的对象;即,在读取时,从文件中读取的codecvt
流将转换为char
流,但在写入时,char
流将转换为wchar_t
流,然后写入文件。对于wchar_t
,char
对象是标准std::wifstream
的实例,通常将UTF-8转换为UCS-16。
正如the MSDN documentation page for basic_filebuf
所述:
basic_filebuf 类型的对象是使用char *类型的内部缓冲区创建的,而不管类型参数 Elem 指定的 char_type 。这意味着在将Unicode字符串(包含wchar_t字符)写入内部缓冲区之前,它将转换为ANSI字符串(包含char字符)。
类似地,当读取Unicode字符串(包含codecvt
个字符)时,std::codecvt<wchar_t, char, mbstate_t>
将从文件读取的ANSI字符串转换为返回到wchar_t
的{{1}}字符串,其他阅读操作。
如果您将basic_filebuf
的编码更改为UTF-8,原始程序应该可以正常工作。
供参考,这对我有用:
wchar_t
请注意,getline
的编码也将是UTF-8(通常)。
答案 1 :(得分:1)
为什么要使用wifstream
- 您是否确信您的文件包含一系列(系统相关的)宽字符?几乎可以肯定,情况并非如此。 (最值得注意的是,因为系统的宽字符集在C ++程序范围之外并不明确。)
相反,只需按原样读取输入字节流并相应地回显它:
std::ifstream infile(thefile);
std::string line;
std::vector<std::string> input;
while (std::getline(infile, line)) // like this!!
{
input.push_back(line);
}
// etc.