C++ 从字节缓冲区读取无符号 int 值

问题描述 投票:0回答:1

各位程序员大家好, 休息了 20 多年后,我开始重新开始编码,并开始重新学习 C++(一种我几乎从未使用过的语言,我曾经是一个 Object Pascal 人)。 所以,我认为自己是一个十足的n00b。 因此,如果我的问题很愚蠢,抱歉,但我被困住了。 (PS:英语是我的第五语言,所以请原谅可能出现的语法错误)。

(P.P.S.:如果我的问题重复,我没有找到它,抱歉)

我尝试编写一个程序,将整个文件读入字节流,然后从中读取值。我期望的(数字)值是 2 字节或 4 字节、无符号、小端字节序。 (是的,我已经掌握了基础知识)。

这是我的(全局)变量:

std::string File_Content = "";  // entire file contents in ByteArray
unsigned __int32 File_Pos = 0;  // position in the File_Content, next Byte about to be read

这是执行读取操作的函数: (通过引用返回值,因此没有无意义的复制,因为也有字符串)

static __int8 Read2Bytes(unsigned __int32 iPos, unsigned __int8 iEndian, unsigned __int16 &iReturn)
{
   if (iEndian == 0)  // Little Endian
   { 
      // Push "second" byte to High Byte
      iReturn = File_Content[iPos] | (File_Content[iPos + 1] << 8);
   }  // end if (iEndian == 0)
   else
   {  // Big Endian, not important right now
   }  // end else (iEndian == 0)

   File_Pos += 2;  // move the Position-Marker along
   return 0;
}  // end Read2Bytes

这是我调用函数来读取 2-Byte-Int:

unsigned __int16 iTimeStamp = 0;      // 2 bytes
Read2Bytes(File_Pos, 0, iTimeStamp);  // Position in the FileStream, Endian, Return Value)

现在,根据 WinHex 的说法,我希望从 ByteStream 中读取的字节读取为

0xC6 0x9D
(按该顺序)。所以,在字节序化之后,我希望“iTimeStamp”返回为
0x9DC6
,对吗?

但事实上,它返回为

0xFFC6
,对于我的一生,我无法弄清楚为什么。

我有另一个函数应该读取 4 个字节,小端,LowWord-HighWord, 我也有同样的问题。

请任何人睁开我的眼睛,为什么我的 HighBytes 在翻译中迷失在某个地方。

提前致谢!

编辑: 我做了一些实验来调试这个问题,并尝试了这个:

static __int8 Read2Bytes(unsigned __int32 iPos, unsigned __int8 iEndian, unsigned __int16 &iReturn)
{
   unsigned __int8 bHiByte, bLoByte;  // both bytes separately

   if (iEndian == 0)  // Little Endian
   { 
      // Not-Working Version
      //iReturn = File_Content[iPos] | (File_Content[iPos + 1] << 8);

      // new attempt, byte-by-byte
      bLoByte = File_Content[iPos];       // read "first" byte
      bHiByte = File_Content[iPos + 1];   // read "2nd" byte
      iReturn = (bHiByte << 8) | bLoByte; // endian them together

   }  // end if (iEndian == 0)

   (Rest unchanged)

突然间它就起作用了!从字节

0xC6
0x9D
我确实得到了
0x9DC6

我的第一次尝试做错了什么? 因为,这个程序应该有利于性能,而且我不认为声明 2 个额外的变量(包括它们的垃圾回收)是最快的方法。

或者有一种完全不同的、更好的方法吗?请赐教!

谢谢!

c++ endianness bit-shift unsigned-integer
1个回答
0
投票

您的

char
类型已签名。
char
是您从
std::string
得到的。

除非您非常清楚自己在做什么,否则您不应该对有符号类型值进行移位或位调整。立即投射到

unsigned char

iReturn = (unsigned char)File_Content[iPos] 
        | ((unsignd char)File_Content[iPos + 1] << 8);

现场演示

© www.soinside.com 2019 - 2024. All rights reserved.