因为您看到类似 ■a a a a a a a 1 1 1 1 1 1 1 2 2 2 2 2 2 2 ♦ 打印到控制台,看起来input.txt
以 UTF-16 编码进行编码,可能是 UTF-16 LE +BOM。如果将文件的编码更改为 UTF-8,则可以使用原始代码。
使用UTF-8的原因是,无论文件流的char类型如何,basic_fstream
的底层basic_filebuf
uses a codecvt
转换流的对象char
与 char 类型对象流之间的对象;即在阅读时,char
从文件中读取的流被转换为wchar_t
流,但是在写入时,wchar_t
流被转换为char
然后写入文件的流。如果是std::wifstream
, the codecvt
对象是标准的一个实例std::codecvt<wchar_t, char, mbstate_t>
,通常将 UTF-8 转换为 UCS-16。
正如上所解释的MSDN 文档页面basic_filebuf:
类型对象基本文件缓冲区使用 char * 类型的内部缓冲区创建,无论字符类型由类型参数指定Elem。这意味着 Unicode 字符串(包含 wchar_t 字符)在写入内部缓冲区之前将被转换为 ANSI 字符串(包含 char 字符)。
类似地,当读取 Unicode 字符串(包含wchar_t
字符),basic_filebuf
将从文件中读取的 ANSI 字符串转换为wchar_t
字符串返回到getline
和其他读取操作。
如果你改变编码input.txt
转换为 UTF-8,您的原始程序应该可以正常工作。
作为参考,这对我有用:
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
int main()
{
using namespace std;
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();
return EXIT_SUCCESS;
}
请注意,编码result.txt
也将是 UTF-8(通常)。