【发布时间】:2017-07-01 19:51:06
【问题描述】:
大家好,我一直在到处寻找有关如何完成这项特定任务的见解。我看到了类似的东西,但没有明确的解释。我正在尝试读取 bin 文件并计算特定数字出现的次数。我看到了使用 .txt 文件的示例,使用 getline 似乎非常简单。我试图复制类似的结构,但使用二进制文件。
int main() {
int searching = 3;
int counter = 0;
unsigned char * memblock;
long long int size;
//open bin file
ifstream file;
file.open("threesData.bin", ios:: in | ios::binary | ios::ate);
//read bin file
if (file.is_open()) {
cout << "it opened\n";
size = file.tellg();
memblock = new unsigned char[size];
file.seekg(0, ios::beg);
file.read((char * ) memblock, size);
while (file.read((char * ) memblock, size)) {
for (int i = 0; i < size; i++) {
(int) memblock[i];
if (memblock[i] == searching) {
counter++;
}
}
}
}
file.close();
cout << "The number " << searching << " appears ";
cout << counter << " times!";
return 0;
}
当我运行程序时,很明显它打开了,但它不计算我正在搜索的数字。我做错了什么?
【问题讨论】:
-
请记住,在二进制文件中,int 将(可能)是 4 个字节,而不是 UTF-8 或 ASCII 文本文件中的 1 个字节。您将使用 '\x03' 字节计算任何内容,这可能远远超出您的讨价还价。
-
那么我应该将搜索更改为 uint32_t 吗?或者我的所有变量都应该指定为那种类型?因为我知道二进制文件包含 32 位整数。
-
您应该将输入缓冲区转换为不同的类型。另外,我认为您的代码还有许多其他问题。您似乎在进入循环之前调用了
file.read()两次,您打开文件以使用起始位置(0)确定缓冲区大小,然后读取大小为0...选择一个合理的值:4096 左右。 -
我会给你一些建议,但你应该考虑清楚:从缓冲区读取,确保
size % sizeof(int) == 0,然后转换为int* int= = (int*)buffer并迭代for (size_t i = 0; i < size / sizeof(int); ++i);这应该可以帮助您继续前进。 -
感谢您的建议,我希望我能更清楚地理解它......所以我删除了额外的 file.read() 我认为我需要它来启动 while 循环......我认为 ios::ate 允许最初读取整个文件,然后 file.tellg() 会确定它的大小? ....所以对于我的缓冲区大小,我可以选择一个任意大的数字?...