繁体   English   中英

在C ++中使用按位运算符将4个字符更改为int

[英]Using bitwise operators in C++ to change 4 chars to int

我必须做的是以二进制模式打开一个文件,其中包含要被解释为整数的存储数据。 我见过其他例子,例如Stackoverflow - 从char *数组中读取“整数”大小的字节。 但我想尝试采取不同的方法(我可能只是顽固,或愚蠢:/)。 我首先在十六进制编辑器中创建了一个简单的二进制文件,内容如下。

00 00 00 47 00 00 00 17 00 00 00 41
如果12个字节被分成3个整数,则该(应该)等于71,23和65。

在二进制模式下打开此文件并将4个字节读入字符数组后,如何使用按位运算使char [0]位成为int的前8位,依此类推,直到每个字符串的位为int。

 
My integer = 00        00        00        00  
 +           ^         ^         ^         ^
Chars      Char[0]  Char[1]   Char[2]   Char[3]
             00        00        00        47


So my integer(hex) = 00 00 00 47 = numerical value of 71

另外,我不知道我的系统的字节顺序是如何发挥作用的,所以有什么我需要记住的吗?

这是我到目前为止的代码片段,我只是不知道接下来要采取的步骤。


std::fstream myfile;
    myfile.open("C:\\Users\\Jacob\\Desktop\\hextest.txt", std::ios::in | std::ios::out | std::ios::binary);
    if(myfile.is_open() == false)
    {
        std::cout << "Error" << std::endl;
    }
    char* mychar;
    std::cout << myfile.is_open() << std::endl;
    mychar = new char[4];
    myfile.read(mychar, 4);

我最终计划处理从文件中读取浮点数,最终可能是自定义数据类型,但首先我只需要更熟悉使用按位运算。 谢谢。

你想要按位左移运算符:

typedef unsigned char u8;  // in case char is signed by default on your platform
unsigned num = ((u8)chars[0] << 24) | ((u8)chars[1] << 16) | ((u8)chars[2] << 8) | (u8)chars[3];

它的作用是将左参数向左移动指定的位数,从右边添加零作为填充。 例如, 2 << 1是4,因为2是二进制的10并且向左移动一个给出100 ,即4。

这可以用更通用的循环形式编写:

unsigned num = 0;
for (int i = 0; i != 4; ++i) {
    num |= (u8)chars[i] << (24 - i * 8);    // += could have also been used
}

系统的字节顺序在这里并不重要; 你知道文件中表示的字节顺序,它是常量的(因此是可移植的),所以当你读入字节时,你知道如何处理它们。 CPU /内存中整数的内部表示可能与文件的内部表示不同,但代码中对它的逻辑按位操作与系统的字节顺序无关; 最低有效位始终位于右侧,最左侧位于代码中。 这就是为什么移动是跨平台的 - 它在逻辑位级别运行:-)

你有没有想过使用Boost.Spirit来制作二进制解析器? 当你开始时,你可能会遇到一些学习曲线,但如果你想稍后扩展你的程序以阅读浮点数和结构化类型,你将有一个很好的基础开始。

精神有很好的记录,是Boost的一部分。 一旦你了解它的来龙去脉,它真的令人难以置信,你可以用它做什么,所以如果你有一点时间玩它,我真的建议看一看。

否则,如果您希望您的二进制文件是“可移植的” - 即您希望能够在big-endian和little-endian机器上读取它,则需要某种字节顺序标记(BOM)。 这将是您首先阅读的内容,之后您可以逐字节地读取整数。 最简单的事情可能是将它们读入一个联合(如果你知道你要读的整数的大小),就像这样:

union U
{
    unsigned char uc_[4];
    unsigned long ui_;
};

将数据读入uc_成员,如果需要更改字节顺序并从ui_成员读取值,则交换字节。 没有转移等等 - 除了交换,如果你想改变字节顺序..

HTH

RLC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM