【问题标题】:How do I use basic_filebuf with element type other than char?如何将 basic_filebuf 与 char 以外的元素类型一起使用?
【发布时间】:2009-09-14 19:53:29
【问题描述】:

假设我想使用basic_filebuf 读取文件的内容。我有一个名为boost::uintmax_t 的类型,其大小为8 bytes。我正在尝试编写以下内容:

typedef basic_filebuf<uintmax_t> file;
typedef istreambuf_iterator<uintmax_t> ifile;

file f;
vector<uintmax_t> data, buf(2);

f.open("test.txt", std::ios::in | std::ios::binary);
f.pubsetbuf(&buf[0], 1024);

ifile start(&f), end;
while(start != end)
{
    data.push_back(*start);
    start++;
}

问题是有些bytes 被阅读,有些则没有。例如,假设在编号为1-9 的文件中有9 bytes

|1|2|3|4|5|6|7|8|9|

当我运行上述代码时,只有一个元素被推回data,其中包含4 bytes仅来自f中的原始数据:

[0|0|0|0|4|3|2|1] --> only element in [data]

我做错了什么?这是我第一次直接使用basic_filebuf,虽然我知道如何使用filebuf

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    basic_filebuf 处理“内部”字符类型和“外部”字符类型。 “外部”是文件的内容,总是字节。 “内部”的参数是模板参数,是在其与程序的接口中使用的参数。为了在两者之间进行转换,basic_filebuf 使用其语言环境的 codecvt 方面。

    所以如果你想让它直接写你给它的字节,你有两个选择:

    • 使用仅在“内部”和“外部”编码之间转换的“退化”编解码器,而不是尝试执行转换。
    • 使用 basic_filebuf,确保使用“经典”语言环境,并进行强制转换以 char 自己

    【讨论】:

    • 似乎 MSVC 的 basic_filebuf 实现可能会跳过使用 codecvt facet 并且只会直接写入内部类型而不将其转换为外部类型,即使这不是正确的行为。
    【解决方案2】:

    basic_filebuf 类型的对象是 使用内部缓冲区创建 类型 char * 不管 char_type 指定的类型 参数 Elem。这意味着一个 Unicode 字符串(包含 wchar_t 字符)将被转换为 ANSI 字符串(包含 char 字符)在写入之前 内部缓冲区。存储 Unicode 缓冲区中的字符串,创建一个新的 wchar_t 类型的缓冲区并设置它 使用 basic_streambuf::pubsetbuf() 方法。

    来自http://msdn.microsoft.com/en-us/library/tzf8k3z8(VS.80).aspx

    【讨论】:

    • 谢谢。即使我使用 pubsetbuf() 的值 (*start) 仅对 4 个字节是正确的,其他字节是零。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多