1

我必须首先读取西里尔文的文件,然后随机选择随机行数并将修改后的文本写入不同的文件。拉丁字母没有问题,但我遇到了西里尔文字的问题,因为我得到了一些垃圾。所以这就是我尝试做这件事的方式。

说,文件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();

那么我怎样才能使用西里尔文,使它产生可读的东西,而不仅仅是符号呢?

4

2 回答 2

2

因为您看到类似 ■aaaaaaa 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使用codecvt对象将对象流转换为charchar 类型的对象流或从 char 类型的对象流转换;即在读取时,char将从文件中读取的流转换为wchar_t流,但在写入时,将wchar_t流转换为char流,然后写入文件。在 的情况下std::wifstreamcodecvt对象是标准的实例std::codecvt<wchar_t, char, mbstate_t>,一般将 UTF-8 转换为 UCS-16。

正如MSDN 文档页面basic_filebuf上所解释的:

basic_filebuf类型的对象是使用 char * 类型的内部缓冲区创建的,而不管类型参数Elem指定的char_type是什么。这意味着 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(通常)。

于 2011-09-23T12:36:14.273 回答
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.
于 2011-09-22T22:46:47.023 回答