gpt4 book ai didi

c++ - 为什么 std::basic_fstream 不起作用?

转载 作者:行者123 更新时间:2023-12-03 07:09:13 26 4
gpt4 key购买 nike

尝试编译此代码时:

std::fstream file("file.name", std::ios::out | std::ios::binary);
uint8_t buf[BUFSIZE];
//Fill the buffer, etc...
file.write(buf, BUFSIZE);
编译器会警告我从 unsigned char 进行的 oh-not-so-healthy 转换至 char调用 write() .如 std::fstream实际上只是 std::basic_fstream<char> 的 typedef , 可以认为使用 std::basic_fstream<uint8_t>而是允许他们在没有警告的情况下编译上面的代码,如 write()需要模板类型的指针。
这当然可行,但又出现了另一个问题。即使这段代码编译得很好:
std::basic_fstream<uint8_t> file("file.name", std::ios::out | std::ios::binary);
uint8_t buf[BUFSIZE];
//Fill the buffer, etc...
file.write(buf, BUFSIZE);
现在调用 write() 将失败,即使以前的版本正在运行(忽略编译器警告)。我花了一段时间来查明标准 C++ 库代码中异常是从哪里引发的,但我仍然不太明白这里的情况。看起来像 std::basic_fstream使用一些字符编码机制,并且因为有一个为 char 定义的但 unsigned char 没有,文件流在尝试使用“错误的”字符数据类型时会静默失败……至少我是这么看的。
但这也是我不明白的。不需要任何字符编码。我什至不以文本模式打开文件,我想处理二进制数据。这就是我使用 uint8_t 类型的数组的原因。 ,而不是 char,使用这种数据类型感觉更自然,而不是普通的旧 char .但在我决定放弃 uint8_t 之前数据类型,只接受使用 char缓冲区,或开始使用自定义数组 byte数据类型定义为 char ,我想问两个问题:
  • 究竟是什么机制阻止我使用无符号字符数据类型?它真的与字符编码有关,还是有其他用途?为什么文件流适用于有符号字符数据类型,但不适用于无符号数据类型?
  • 假设我仍然想使用 std::basic_fstream<uint8_t> ,无论它多么(不)合理 - 有没有办法实现这一点?
  • 最佳答案

    std::basic_fstream<unsigned char>不起作用,因为它使用 std::char_traits<unsigned char>但标准库没有提供这样的特化,见 std::char_traits 完整的细节。
    如果你想读/写二进制数据,你需要使用std::basic_fstream<char> , 用 std::ios_base::binary 打开它标记并使用 std::basic_ostream<CharT,Traits>::write 写入二进制数据的函数。
    这是一个遗留问题,因为所有 char类型可用于表示二进制数据。标准库使用 char可能是因为这是最短的打字和阅读工作。

    What exactly is that mechanism that stops me from using unsigned character datatype?


    没有 std::char_traits<unsigned char>特化。

    Is it really something related to character encoding, or does it serve some other purpose?

    std::char_traits在其接口(interface)中准确定义了一些用途,但不包括解码/编码。后者由 codecvt 完成,请参阅那里的用法示例。

    Why file stream works fine with signed character data types, but not for unsigned ones?


    因为 std::basic_ostream<CharT,Traits>::write 接受 CharT ,您为流指定的第一个模板参数。它写入与读取相同的字符类型并使用 codecvtCharT 转换为字节。

    Assuming that I still would want to use std::basic_fstream<uint8_t>, regardless how (un)reasonable it is - is there any way to achieve that?


    标准类和函数模板不能专门用于内置类型, if I am not mistaken .您需要使用 std::char_traits 创建另一个类接口(interface)并将其指定为标准流的第二个模板参数。我想,你需要一个非常强大(哲学)的理由来卷起袖子去做。
    如果你不这样做,你可能想继续使用 std::fstream<char>stream.write(reinterpret_cast<char const*>(buf), sizeof buf); .

    关于c++ - 为什么 std::basic_fstream<unsigned char> 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64884491/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com