为什么 ostream::write() 在 C++ 中需要“const char_type*”而不是“const void*”?

Why does ostream::write() require ‘const char_type*’ instead of ‘const void*’ in C++?

C 中的 fwrite() 函数使用 const void *restrict buffer 作为第一个参数,因此您可以直接将指向 struct 的指针作为第一个参数传递。
http://en.cppreference.com/w/c/io/fwrite
例如fwrite(&someStruct, sizeof(someStruct), 1, file);

但在 C++ 中,ostream::write() 需要 const char_type*,这迫使您使用 reinterpret_cast。 (在 Visual Studio 2013 年,是 const char*。)
http://en.cppreference.com/w/cpp/io/basic_ostream/write
例如file.write(reinterpret_cast<char*>(&someStruct), sizeof(someStruct));

几乎在所有情况下,要写入文件的二进制数据都不是char数组,那么为什么标准更喜欢看起来更复杂的样式?

P.S.
1、其实我用的是ofstream中的write()方法,使用的是ios::binary模式,但是根据参考,它继承了ofstream。所以我上面用的是ostream::write()
2. 如果要打印字符流,可以使用operator<<()write()方法不是为写原始数据而设计的吗?
3、如果write()不是写二进制数据的方式,那么在标准范围内的方式是什么? (尽管由于不同平台上的各种内存对齐策略,这可能会影响代码的可移植性)

char_type不完全是char *,是流的模板参数,表示流的字符类型:

template<typename _CharT, typename _Traits>
class basic_ostream : virtual public basic_ios<_CharT, _Traits>
{
public:
    // Types (inherited from basic_ios):
    typedef _CharT                  char_type;
    <...>

std::ostream只是char实例化:

typedef basic_ostream<char> ostream;

将此描述为 C 与 C++ 的对比具有误导性。 C++ 像 C 一样提供 std::fwrite(const void*, ...)。C++ 选择更具防御性的地方特别是 std::iostream 版本。

"Almost in all cases the binary data to be written to files is not char array"

这是有争议的。在 C++ 中,在 I/O 中添加间接级别并不罕见,因此对象被流式传输或序列化为方便的 - 并且可能是可移植的(例如,字节序标准化,没有或带有标准化结构填充) - 表示,然后deserialised/parsed 重读时。逻辑通常与所涉及的各个对象一起本地化,因此顶级对象不需要知道其成员的内存布局的详细信息。序列化和流式传输倾向于在字节级别被认为/缓冲等 - 更适合字符缓冲区,并且 read()write() return 当前可以传输的一些字符- 再次是在角色级别而不是对象级别 - 所以假装不是很有成效,否则你会在恢复部分成功的 I/O 操作时一团糟。

天真地完成原始二进制写入/读取有点危险,因为它们不处理这些问题,所以这些函数的使用稍微困难一些可能是一件好事,reinterpret_cast<> 有点代码异味/警告。

也就是说,C++ 使用 char* 的一个不幸方面是,它可能会鼓励一些程序员首先读取字符数组,然后使用不适当的强制转换 "reinterpret" 上的数据fly - 就像 int* 以一种可能未正确对齐的方式瞄准字符缓冲区。

If you want to print a stream of characters, you could use operator<<(). Isn't write() method designed for writing raw data?

使用 operator<<() 打印字符流是有问题的,因为唯一相关的重载采用 const char* 并需要一个 '[=21=]'/NUL 终止的缓冲区。如果您想在输出中打印一个或多个 NUL,那么它就毫无用处。此外,当从较长的字符缓冲区开始时 operator<< 通常会笨拙、冗长且容易出错,需要 NUL 在流式传输中来回交换,有时 and/or 内存使用问题,例如当写一些 - 但不是结尾 - 你不能交换 NUL 的长字符串文字时,或者当字符缓冲区可能正在从其他不应看到 NUL 的线程中读取时。

所提供的 std::ostream::write(p, n) 函数避免了这些问题,让您可以准确指定要打印的数量。

瑞,

来自 cplusplus.com 站点的 ostream::write 的签名是:

ostream& write (const char* s, streamsize n);

刚刚在VS2013上查了一下,你写起来很轻松:

std::ofstream outfile("new.txt", std::ofstream::binary);
char buffer[] = "This is a string";
outfile.write(buffer, strlen(buffer));

在C/C++中,char是表示字节的数据类型,所以char[]的自然数据类型二进制数据。

我认为,您的问题最好针对 C/C++ 未设计为 "bytes" 和 "characters" 具有不同数据类型的事实,而不是设计流库的数量。