C++ iostream>>运算符的行为与 get() unsigned char 不同

发布于 2024-11-25 20:45:11 字数 818 浏览 1 评论 0原文

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

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

我注意到,如果我使用 >> ,从文件中读取下一个无符号字符的方式会有所不同。 istream 类中的运算符与 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

我不确定它们之间有何关系? (它们不是彼此的 2 补码?)

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

I was working on a piece of code to do some compression, and I wrote a bitstream class.

My bitstream class kept track of the current bit we are reading and the current byte (unsigned char).

I noticed that reading the next unsigned character from the file was done differently if I used the >> operator vs get() method in the istream class.

I was just curious why I was getting different results?

ex:

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

vs.

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

Additional Info:

To be specific the byte I was reading was 0x0A however when using >> it would read it as 0x6F

I'm not sure how they're even related ? (they're not the 2s complement of each other?)

The >> operator is also defined to work for unsigned char as well however (see c++ istream class reference

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

漫雪独思 2024-12-02 20:45:11

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

operator>> is for formatted input. It'll read "23" as an integer if you stream it into an int, and it'll eat whitespace between tokens. get() on the other hand is for unformatted, byte-wise input.

不甘平庸 2024-12-02 20:45:11

如果您不解析文本,请勿使用 operator>>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

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

If you aren't parsing text, don't use operator>> or operator<<. You'll get weird bugs that are hard to track down. They are also resilient to unit tests, unless you know what to look for. Reading a uint8 for instance will fail on 9 for instance.

edit:

#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;
}

produces:

testing z
7a vs 7a
testing 

is not good
a vs 21

I suppose that would never have been evident a priori.

皇甫轩 2024-12-02 20:45:11

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

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

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

C++'s formatted input (operator >>) treats char and unsigned char as a character, rather than an integer. This is a little annoying, but understandable.

You have to use get, which returns the next byte, instead.

However, if you open a file with the binary flag, you should not be using formatted I/O. You should be using read, write and related functions. Formatted I/O won't behave correctly, as it's intended to operate on text formats, not binary formats.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文