将narrow(char)输入流重新解释为宽(wchar_t)流

zet*_*t42 9 c++ boost iostream boost-iostreams

关于SO的第一个问题!:d

我给了一个std::istream包含UTF-16编码字符串的字符串.想象一下这样打开的UTF-16编码文本文件:

std::ifstream file( "mytext_utf16.txt", std::ios::binary );
Run Code Online (Sandbox Code Playgroud)

我想将此流传递给一个带std::wistream&参数的函数.我无法将文件流类型更改为std :: wifstream.

问题:标准或boost库中是否有任何工具可以让我"重新解释"istream作为一个wistream?

我想象一个类似于std :: wbuffer_convert的适配器类,除了它不应该进行任何编码转换.基本上对于从适配器类读取的每个wchar_t,它应该只从关联的istream中读取两个字节,并将reinterpret_cast它们读取到wchar_t.

我已经创建了一个使用boost :: iostreams的实现,可以像这样使用,就像一个魅力:

std::ifstream file( "mytext_utf16.txt", std::ios::binary );

// Create an instance of my adapter class.
reinterpret_as_wide_stream< std::ifstream > wfile( &file );

// Read a wstring from file, using the adapter.
std::wstring str;
std::get_line( wfile, str );    
Run Code Online (Sandbox Code Playgroud)

那我为什么要问?因为我喜欢重用现有代码而不是重新发明轮子.

ove*_*eas 2

这是正在进行中的工作

\n\n

这不是您应该使用的内容,但如果您还没有考虑过做这样的事情,则可能会提示您可以开始做什么。如果这没有帮助或者当您可以找到更好的解决方案时,我很高兴删除或扩展此答案。

\n\n

据我了解,您想要读取 UTF-8 文件并将每个单个字符简单地转换为 wchar_t。

\n\n

如果标准设施的功能太多了,您就不能编写自己的方面吗?

\n\n
#include <codecvt>\n#include <locale>\n#include <fstream>\n#include <cwchar>\n#include <iostream>\n#include <fstream>\n\nclass MyConvert\n{\n public:\n  using state_type = std::mbstate_t;\n  using result = std::codecvt_base::result;\n  using From = char;\n  using To = wchar_t;\n  bool always_noconv() const throw() {\n    return false;\n  }\n  result in(state_type& __state, const From* __from,\n    const From* __from_end, const From*& __from_next,\n    To* __to, To* __to_end, To*& __to_next) const\n  {\n    while (__from_next != __from_end) {\n      *__to_next = static_cast<To>(*__from_next);\n      ++__to_next;\n      ++__from_next;\n    }\n    return result::ok;\n  }\n  result out(state_type& __state, const To* __from,\n      const To* __from_end, const To*& __from_next,\n      From* __to, From* __to_end, From*& __to_next) const\n  {\n    while (__from_next < __from_end) {\n      std::cout << __from << " " << __from_next << " " << __from_end << " " << (void*)__to << \n        " " << (void*)__to_next << " " << (void*)__to_end << std::endl;\n      if (__to_next >= __to_end) {\n        std::cout << "partial" << std::endl;\n        std::cout << "__from_next = " << __from_next << " to_next = " <<(void*) __to_next << std::endl;\n        return result::partial;\n      }\n      To* tmp = reinterpret_cast<To*>(__to_next);\n      *tmp = *__from_next;\n      ++tmp;\n      ++__from_next;\n      __to_next = reinterpret_cast<From*>(tmp);\n    }\n    return result::ok;\n  }\n};\n\nint main() {\n  std::ofstream of2("test2.out");\n  std::wbuffer_convert<MyConvert, wchar_t> conv(of2.rdbuf());\n  std::wostream wof2(&conv);\n  wof2 << L"\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82 \xd0\xb2\xd0\xbe\xd0\xbf\xd1\x80\xd0\xbe\xd1\x81\xd0\xbe\xd0\xb2 \xd0\xb8 \xd0\xbe\xd1\x82\xd0\xb2\xd0\xb5\xd1\x82\xd0\xbe\xd0\xb2 \xd0\xb4\xd0\xbb\xd1\x8f \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2";\n  wof2.flush();\n  wof2.flush();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不是您应该在代码中使用的内容。如果方向正确,您需要阅读文档,包括此方面所需的内容、所有这些指针的含义以及需要如何写入它们。

\n\n

如果您想使用这样的东西,您需要考虑应该为构面使用哪些模板参数(如果有)。

\n\n

更新我现在已经更新了我的代码。我认为输出函数现在更接近我们想要的了。它并不漂亮,只是一个测试代码,我仍然不确定为什么__from_next不更新(或保留)。

\n\n

目前的问题是我们无法写入流。使用 gcc,我们只是失去了 wbuffer_convert 的同步,对于 clang,我们得到一个 SIGILL。

\n