2013-06-13 37 views
3

我在basic_ostream对象的write方法读了,这就是我对cppreference发现:关于性病:: basic_ostream ::写

basic_ostream& write(const char_type* s, std::streamsize count); 

表现为UnformattedOutputFunction。构造并检查哨兵对象后,输出字符数组中第一个元素由s指向的连续位置中的字符。

  • 恰好count字符插入
  • 插入输出序列失败(在此情况下setstate(badbit)称)

:直到以下情况之一时字符被插入到输出序列所以我得到它将一个缓冲区中的字符块写入流中。字符数是由count指定的字节数。但是有一些我不确定的事情。这是我的问题:

  • 我应该使用write只有当我想指定我想多少字节写入流?因为通常当您打印一个char数组时,它将打印整个数组,直到达到空字节,但是当您使用write时,您可以指定要写入多少个字符。

    char greeting[] = "Hello World"; 
    
    std::cout << greeting;  // prints the entire string 
    std::cout.write(greeting, 5); // prints "Hello" 
    

    但也许我误解了这个东西。

  • 而且我经常会看到这样使用write代码示例:

    stream.write(reinterpret_cast<char*>(buffer), sizeof(buffer)); 
    

    为什么reinterpret_castchar*被使用?我应该何时知道在写入流时做类似的事情?

如果任何人都可以帮助我解决这两个问题,将不胜感激。

回答

2

•我是否应该仅在要指定要写入流的字节数时使用写入?

是 - 你应该使用write当有您希望我们写入流,才能在内存中连续排列的数据字节的具体数量。但是有时你可能需要特定数量的字节,需要以另一种方式获取它们,例如通过格式化double的ASCII表示以具有特定的宽度和精度。其他时间你可以使用>>,但是它必须是非内置类型的用户定义的,当它被定义时 - 通常更好,但它可能会更糟 - 你的目的 - 它会打印任何类设计器选择的,包括潜在的数据,这些数据是通过指针或引用以及感兴趣的静态数据和/或动态计算的值从对象链接的。它可能会改变数据表示形式:例如将二进制double s转换为ASCII表示,或者确保网络字节顺序,而不管主机的字节顺序如何。它也可以省略某些对象的数据,如缓存项,用于管理计数器但不填充等方面的数据,数组元素没有逻辑部分..

为什么是烧焦了的reinterpret_cast *正在使用?我应该何时知道在写入流时做类似的事情?

write()函数签名期望const char*参数,所以这个转换正在完成。只要您无法获得char*的数据,您就需要使用演员表。

演员阵容反映出write()将对象第一个字节处开始的数据视为8位值,而不考虑数据的实际预制类型。这与能够执行诸如float的最后一个字节的write()和出现在相同结构中的下一个double的前3个字节之类的事情 - 在reinterpret_cast<>之后所有的数据边界和解释都会丢失。 (当你从输入流中执行read()字节时,你实际上应该更加小心......假如你读取的数据构成double,当写入内存时,这些数据没有正确对齐double,然后尝试使用它作为double,你可能会得到一个SIGBUS或类似的对齐异常从您的CPU或性能下降取决于您的系统。)

1

basic_ostream::write及其对应部分basic_istream::read用于在数据流上执行未格式化的I/O。通常,这是原始的二进制数据,可能包含或不包含可打印的ascii字符。

read/write和其他格式的运营商如<<>>getline等之间的主要区别在于,前者不会使对数据的任何假设正在对工作 - 你必须在什么字节得到完全控制读取并写入流。与可能跳过空格的后者相比,丢弃或忽略它们等。

要回答第二个问题,reinterpret_cast <char *>用于满足函数签名并且一次处理一个字节的缓冲区。不要让类型char欺骗你。使用char的原因是因为它是语言提供的最小的内置原语类型。也许一个更好的名字可能类似uint8,表明它确实是一个无符号的字节类型。

+0

因此,通过您的解释,理论上你可以传递一个'bool *'到'reinterpret_cast'因为它也是一个字节? – 0x499602D2

+0

@ 0x499602D2好点。这将是一种类型不匹配。 – greatwolf

+0

@ 0x499602D2:它不会是一个类型不匹配......“布尔*”就像任何其他指针一样......它有一些字节数(对于32位应用程序通常是4,对于64位通常是8 ),你可以'reintrepret_cast'到'c​​har *'并开始从存储'bool'的地址写入字节。在C++ 03中,“bool”的大小是未指定的,但C++ 11引入了默认和程序员控制......对它们没有特别的了解,特别是“bool *”不是某种指向(如果可能的话)转换成char *'怪异/有损)。 –