不能用wofstream将中文字符写入文本文件

时间:2018-02-16 09:23:16

标签: c++ winapi dev-c++ wofstream

我使用std::wofstream在文本文件中写字符。我的字符可以有来自不同语言(英语到中文)的字符。 我想将vector<wstring>打印到该文件中。 如果我的矢量只包含英文字符,我可以毫无问题地打印它们。 但如果我写中文字符,我的文件仍然是空的。

我浏览了stackoverflow,所有答案基本上都是为了使用库中的函数:

#include <codecvt>

我无法包含该库,因为我在5.11版中使用了Dev-C ++。 我在所有头文件中都做了#define UNICODE。 我想这个问题有一个非常简单的解决方案。 如果有人可以帮助我,那就太好了。

我的代码:

#define UNICODE
#include <string>
#include <fstream>

using namespace std;

int main()
{
    string Path = "D:\\Users\\\t\\Desktop\\korrigiert_RotCommon_zh_check_error.log";
    wofstream Out;
    wstring eng = L"hello";
    wstring chi = L"程序";

    Out.open(Path, ios::out);

    //works.
    Out << eng;

    //fails
    Out << chi;

    Out.close();

    return 0;
}

亲切的问候

2 个答案:

答案 0 :(得分:1)

首先,事件std::basic_fstream<CharT>的名称暗示它是一个广泛的字符串流,但事实并非如此。它仍然是一个char流。它使用来自语言环境的转换方面将wchars转换为char。

以下是cppreference的说法:

  

通过std::codecvt<CharT, char, std::mbstate_t>执行的所有文件I / O操作都使用流中嵌入的语言环境的imbue方面。

因此,您可以将全局区域设置设置为支持中文或#include <locale> //... const std::locale loc = std::locale(std::locale(), new std::codecvt_utf8<wchar_t>); Out.open(Path, ios::out); Out.imbue(loc); 流的区域设置。在bot情况下,您将获得单字节流。

std::codecvt_utf8

不幸的是MultiByteToWideChar已被弃用[2]。这个MSDN 杂志  文章介绍了如何使用to_utf8 C++ - Unicode Encoding Conversions with STL Strings and Win32 APIs进行UTF-8转换。

此处std::string to_utf8(const CWStringView w) { const size_t size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string output; output.resize(size - 1); WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); return output; } 转换的Microsoft/vcpkg变体:

wstring

另一方面,您可以使用普通二进制流并使用write()写入std::ofstream Out(Path, ios::out | ios::binary); const uint16_t bom = 0xFEFF; Out.write(reinterpret_cast<const char*>(&bom), sizeof(bom)); // optional Byte order mark Out.write(reinterpret_cast<const char*>(chi.data()), chi.size() * sizeof(wchar_t)); 数据。

@Override
  public int getItemViewType(int position) {

     //CHECK IF CURRENT ITEM IS List THEN RETURN ROW
    if(getItem(position) instanceof LISTSECTION)
    {
      return ROW;
    }

     //OTHERWISE RETURN HEADER
    return HEADER;
  }

答案 1 :(得分:-1)

您忘了告诉您的信息流使用哪种语言环境:

Out.imbue(std::locale("zh_CN.UTF-8"));

您显然需要包含<locale>