1

我正在编写一段代码来做一些压缩,我写了一个比特流类。

我的比特流类跟踪我们正在读取的当前位和当前字节(无符号字符)。

我注意到如果我在 istream 类中使用 >> 运算符 vs get() 方法,从文件中读取下一个无符号字符的方式会有所不同。

我只是好奇为什么我得到不同的结果?

前任:

this->m_inputFileStream.open(inputFile, std::ifstream::binary);   
unsigned char currentByte;
this->m_inputFileStream >> currentByte;

对比

this->m_inputFileStream.open(inputFile, std::ifstream::binary);
unsigned char currentByte;
this->m_inputFileStream.get((char&)currentByte);

附加信息:

具体来说,我正在读取的字节是 0x0A 但是当使用 >> 时,它会将其读取为 0x6F

我不确定它们是如何相关的?(它们不是彼此的 2s 补码吗?)

>> 运算符也被定义为适用于 unsigned char 但是(请参阅c++ istream 类参考

4

3 回答 3

2

operator>>用于格式化输入。如果您将其流式传输到 中,它将读取"23"为整数int,并且它会吃掉标记之间的空格。get()另一方面是未格式化的,按字节输入。

于 2011-07-22T15:42:04.510 回答
1

如果您不解析文本,请不要使用operator>>or operator<<。你会得到难以追踪的奇怪错误。它们对单元测试也有弹性,除非你知道要寻找什么。例如,读取 uint8 将在 9 上失败。

编辑:

#include <iostream>
#include <sstream>
#include <cstdint>

void test(char r) {
        std::cout << "testing " << r << std::endl;
        char t = '!';
        std::ostringstream os(std::ios::binary);
        os << r;
        if (!os.good()) std::cout << "os not good" << std::endl;
        std::istringstream is(os.str(), std::ios::binary);
        is >> t;
        if (!is.good()) std::cout << "is not good" << std::endl;
        std::cout << std::hex << (uint16_t)r 
             << " vs " << std::hex << (uint16_t)t << std::endl;
}

int main(int argc, char ** argv) {
        test('z');
        test('\n');
        return 0;
}

产生:

testing z
7a vs 7a
testing 

is not good
a vs 21

我想这永远不会是先验的。

于 2011-07-22T15:47:50.313 回答
0

C++ 的格式化输入 ( operator >>) 将charunsigned char视为字符,而不是整数。这有点烦人,但可以理解。

您必须使用get,它返回下一个字节,而不是。

但是,如果您打开带有二进制标志的文件,则不应使用格式化的 I/O。您应该使用read,write和相关功能。格式化的 I/O 将无法正常运行,因为它旨在操作文本格式,而不是二进制格式。

于 2011-07-22T15:44:33.230 回答