提问人:simsam 提问时间:10/17/2023 最后编辑:user4581301simsam 更新时间:10/24/2023 访问量:78
我在BMP文件中查找二进制子字符串时遇到问题
I'm having issues finding binary substring in my BMP file
问:
所以我有一个小问题。我正在做一项学校作业,我只是不知道如何获得解决方案。因此,赋值需要我以二进制形式读取文件,然后在该读取文件中找到某些位序列。然后,我将打印出找到的序列中第一个位的索引,用于该序列的所有实例。
因此,如果我要编写一个二进制序列并搜索该序列,我将获得如下索引: .现在一切都很好,当我编写代码来为1和0的字符串执行此操作时,但是当我开始实现文件读取和搜索时,我遇到了一个问题。该文件是一个.bmp,以二进制形式读取它应该给我一个像素值的字符串(不太确定如何检查该字符串是否真的是我认为的)。然后,当我去搜索二进制子字符串时,当有很多时,它找不到它的任何实例。我的程序会返回,并且不会循环遍历字符串。10011001001011101
1001
0, 4
std::string::npos
这是我目前拥有的代码:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <filesystem>
using namespace std;
void f(vector<size_t>& poz, string pattern, string filename) {
std::ifstream file(filename, std::ios::binary);
if (file)
{
file.seekg(0, std::ios::end);
std::streampos length = file.tellg();
file.seekg(0, std::ios::beg);
std::vector<char> buffer(length);
file.read(&buffer[0], length);
std::stringstream localStream;
localStream.rdbuf()->pubsetbuf(&buffer[0], length);
string solution = localStream.str();
//after i get the full string i should be able to find the instances of my pattern
//this file contains only white pixels and red (000000000000000011111111) pixels
cout << "Pattern: " << pattern <<endl;
size_t index = solution.find(pattern);
cout << "First found pixel: " << index << endl; // this value is the exact same as npos
cout << "string::npos: " << string::npos;
while (index != string::npos) {
poz.push_back(index);
index = solution.find(pattern, index + pattern.size());
}
}
}
int main() {
vector<size_t> poz;
string file = "test.bmp";
string pattern = "000000000000000011111111"; //looking for red pixels only
f(poz, pattern, file);
for (auto i = poz.begin(); i != poz.end(); i++) {
if (i == (poz.end() - 1))
cout << *i << endl;
else
cout << *i << ", ";
}
}
我不知道我是否搜索了错误的序列,或者我的文件实际上没有转换为二进制字符串,这就是为什么搜索没有发现任何东西的原因。任何帮助都是值得赞赏的。
答:
1赞
simsam
10/17/2023
#1
根据 @user4581301 的观察,我在解决方案之前读取的文件是作为字节传递的,因此我无法找到我希望的匹配项。更改我读取文件的方式解决了我的问题。我没有以二进制模式读取文件并将其直接存储到字符串中,而是决定读取字符,然后将它们转换为位集数组。然后,我将位集数组连接成一个字符串,并使用该函数查找我的出现次数。这个过程很慢,是的,但从技术上讲,按照我的问题工作。我的代码已更改以反映这一点。.find()
void f(std::vector<size_t>& poz, std::string pattern, std::string filename) {
std::ifstream file(filename, std::ios::in | std::ios::out | std::ios::binary);
if (file) {
std::string fileString((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // reading chars instead of bytes
auto size = fileString.size();
file.close();
// Save the characters into 8 bit bitsets
std::bitset<8>* bitsetFile = new std::bitset<8>[size];
std::string convertedFile;
for (int i = 0; i < fileString.size(); i++) {
bitsetFile[i] = std::bitset<8>((int)fileString[i]);
convertedFile = convertedFile + bitsetFile[i].to_string();
}
// use string function .find() to search for red pixels
size_t index = convertedFile.find(pattern);
while (index != std::string::npos) {
poz.push_back(index);
index = convertedFile.find(pattern, index + pattern.size());
}
}
}
评论
std::ifstream file(filename);
以文本模式而不是二进制模式打开文件。不需要的字符替换可能会在程序真正启动之前就将其杀死。我推荐std::ifstream file(filename, std::ios::binary);
向量
的更好方法。std::string
stringstream
std::string::find
std::bitset
101
10100101
01010101
11011101