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)
那我为什么要问?因为我喜欢重用现有代码而不是重新发明轮子.
这是正在进行中的工作
\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}\nRun Code Online (Sandbox Code Playgroud)\n\n这不是您应该在代码中使用的内容。如果方向正确,您需要阅读文档,包括此方面所需的内容、所有这些指针的含义以及需要如何写入它们。
\n\n如果您想使用这样的东西,您需要考虑应该为构面使用哪些模板参数(如果有)。
\n\n更新我现在已经更新了我的代码。我认为输出函数现在更接近我们想要的了。它并不漂亮,只是一个测试代码,我仍然不确定为什么__from_next不更新(或保留)。
目前的问题是我们无法写入流。使用 gcc,我们只是失去了 wbuffer_convert 的同步,对于 clang,我们得到一个 SIGILL。
\n