c++ - 在 C++ 中读取和写入西里尔文文件

标签 c++ file input wofstream wifstream

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

比如说,文件 input.txt

ааааааа
ббббббб
ввввввв

我必须阅读它,并将每一行放入一个 vector 中:

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();

那么我怎样才能使用西里尔字母来生成可读的东西,而不仅仅是符号?

最佳答案

因为您看到像 ■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使用 codecvt转换 char 流的对象对象到/来自 char 类型的对象流;即在阅读时,char从文件中读取的流被转换为 wchar_t流,但在写入时,一个 wchar_t流被转换为 char然后写入文件的流。在std::wifstream的情况下, codecvt object 是标准 std::codecvt<wchar_t, char, mbstate_t> 的一个实例,它通常将 UTF-8 转换为 UCS-16。

the MSDN documentation page for basic_filebuf 中所述:

Objects of type basic_filebuf are created with an internal buffer of type char * regardless of the char_type specified by the type parameter Elem. This means that a Unicode string (containing wchar_t characters) will be converted to an ANSI string (containing char characters) before it is written to the internal buffer.

类似地,当读取 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(通常)。

关于c++ - 在 C++ 中读取和写入西里尔文文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7521842/

相关文章:

c++ - 为什么我不能在 vector 迭代器中直接访问?

java - 在Eclipse环境中打开.dat和.key文件

android - 使用 Uri 从 SD 卡获取文件

VB.Net:按行搜索Word文档

c - 发生错误时,scanf 返回 1 而不是 0

java - 如何在线程 “main”中修复异常java.util.InputMismatchException

C++ - 无法查看使用 WinObj 创建的互斥体

c++ - 将 QString 转换为无符号字符数组

C++,忽略异常并继续代码?

java - 从特定 USB 端口捕获键盘输入