各位程序员大家好, 休息了 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 个额外的变量(包括它们的垃圾回收)是最快的方法。
或者有一种完全不同的、更好的方法吗?请赐教!
谢谢!
您的
char
类型已签名。 char
是您从 std::string
得到的。
除非您非常清楚自己在做什么,否则您不应该对有符号类型值进行移位或位调整。立即投射到
unsigned char
。
iReturn = (unsigned char)File_Content[iPos]
| ((unsignd char)File_Content[iPos + 1] << 8);
现场演示。