我正在使用生成器来生成无符号__int8'ers的随机序列,然后使用ofstream.write()通过此方法将它们写入文件;
void CDataGenerator::GenerateRandom(std::string outputFileName, int length, bool UseEntireRange, int max) {
std::ofstream file;
file.open(outputFileName, std::ifstream::out | std::ifstream::binary);
int count = 0;
unsigned __int8* buf = new unsigned __int8[length];
while (count < length-1) {
int number = 0;
if (UseEntireRange)
number = rand();
else {
int rnd = rand();
number = (int)((double)rnd / RAND_MAX * max);
}
int capacity = 0;
if (number == 0)
capacity = 1;
else
capacity = (int)(floor(log10(number)) + 1);
for (int i = 0; i < capacity; ++i) {
if (count >= length - 2)
break;
buf[count] = ((unsigned __int8)(number / (int)pow(10, capacity - i - 1)));
number %= (int)pow(10, capacity - i - 1);
++count;
}
++count;
buf[count] = BCD_SEPARATOR;
}
file.write((__int8*)&buf[0], length);
delete[] buf;
file.close();
}
在哪里 const static unsigned __int8 BCD_SEPARATOR = 0xff;
然后我尝试使用以下方法读取文件
unsigned __int8* CModel::GetRawData(std::string inputFileName, int &length) {
std::ifstream file(inputFileName, std::ifstream::ate | std::ifstream::binary);
length = file.tellg();
file.close();
file.open(inputFileName, std::ifstream::in | std::ifstream::binary);
unsigned __int8* result = new unsigned __int8[length];
file.read((__int8*)&result[0], length);
file.close();
return result;
}
我的测试生成器创建了这样的序列0x0 0xFF 0x5 0x6 0xFF 0x1 0x9 0xFF 0x8 0xFF但从读取流中我得到了0x0 0xCD 0x5 0x6 0xCD 0x1 0x9 0xCD 0x8 0xCD序列。显而易见,所有0xff都替换为0xcd。它与(__int8 *)强制转换有关,如何解决?
了解了Visual Studio使用的CRT调试堆(我只是假设您使用的是Visual Studio),可以很好地猜测0xCD值来自未初始化的堆内存。问题就变成了:为什么在输出中看到了这一点?要弄清楚原因,您可以使用调试器简单地逐步执行GenerateRandom函数/读取代码。
由此可见问题出在哪里:
for (int i = 0; i < capacity; ++i) {
if (count >= length - 2)
break;
buf[count] = ((unsigned __int8)(number / (int)pow(10, capacity - i - 1)));
number %= (int)pow(10, capacity - i - 1);
++count; //Increment count ONCE
}
++count; //Increment count a SECOND time
buf[count] = BCD_SEPARATOR;
问题在于,当程序离开此处所示的for循环时,count已经增加一次,因此您的“ count”已经在缓冲区中的下一个未初始化的__int8处。然后,在将BCD_SEPARATOR写入缓冲区中的“ count”位置之前,请再次增加“ count”。这将导致程序跳过您实际需要BCD_SEPARATOR的位置。
接下来的问题是,由于在将BCD_SEPARATOR写入缓冲区后和下次进入上述for循环之间不会增加“计数”,因此您会立即覆盖BCD_SEPARATOR。
解决该问题的方法可能是像这样简单地交换内容:
buf[count] = BCD_SEPARATOR;
++count;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句