在C++中使用按位运算符将4个字符更改为int
我必须做的是以二进制模式打开一个文件,该文件包含旨在被解释为整数的存储数据。我见过其他例子,如Stackoverflow-Reading “integer” size bytes from a char* array.,但我想尝试采取不同的方法(我可能只是固执或愚蠢:/)。我首先在十六进制编辑器中创建了一个简单的二进制文件,其内容如下。在C++中使用按位运算符将4个字符更改为int
00 00 00 47 00 00 00 17 00 00 00 41
如果12个字节被分成3个整数,这个(应该)等于71,23和65。
以二进制模式打开此文件并将4个字节读入一个字符数组后,如何使用按位操作使char [0]位成为int的前8位,依此类推,直到每个位char是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
那么我一直在使用大量的提升(线程,文件系统,随机,数学),所以我可能会尝试更熟悉精神类。 – contrapsych 2011-03-17 02:58:42
固执之外,你可以做到这一点通过读取int和再用ntohl使用() – 2011-03-17 02:43:13
你的二进制文件是“big-endian”。所以只要你用big-endian的方式将它的字节转换为整数,你不需要担心计算机的字节序。 – aschepler 2011-03-17 02:44:16
...直到您将您的代码移动到不同的系统,并尝试从大端系统读取数据。那么你会遇到问题。 – Thomi 2011-03-17 02:48:06