在二进制文件中搜索字符串的代码
Posted
技术标签:
【中文标题】在二进制文件中搜索字符串的代码【英文标题】:Code for searching for a string in a binary file 【发布时间】:2011-09-23 04:20:42 【问题描述】:几天前我问过这个问题:
How to look for an ANSI string in a binary file?
我得到了一个非常好的answer,后来变成了一个更难的问题:Can input iterators be used where forward iterators are expected? 现在真的没有达到我能理解的水平。
我还在学习 C++,我正在寻找一种在二进制文件中搜索字符串的简单方法。
谁能给我看一个简单的 C++ 控制台程序的简单代码,它在二进制文件中查找字符串并将位置输出到标准输出?
可能,你能告诉我
文件被复制到内存的版本(假设二进制文件很小)
另一个使用链接问题中的正确方式
很抱歉,这听起来像是我在询问某人的代码,但我只是在学习 C++,我认为如果有人可以发布一些值得学习的高质量代码,其他人可能会从这个问题中受益。
【问题讨论】:
“位置”是什么意思? 第一个字符的字节,从文件开头开始计数。我的意思是告诉() Boyer-Moore algorithm(另见portal.acm.org/citation.cfm?doid=360825.360855) 【参考方案1】:您的需求规范不清楚,例如 - “121”出现在“12121”中的什么位置......只是在第一个字符处(之后在第 4 个字符处继续搜索),还是在第 3 个字符处?下面的代码使用了前一种方法。
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
int main(int argc, const char* argv[])
if (argc != 3)
std::cerr << "Usage: " << argv[0] << " filename search_term\n"
"Prints offsets where search_term is found in file.\n";
return 1;
const char* filename = argv[1];
const char* search_term = argv[2];
size_t search_term_size = strlen(search_term);
std::ifstream file(filename, std::ios::binary);
if (file)
file.seekg(0, std::ios::end);
size_t file_size = file.tellg();
file.seekg(0, std::ios::beg);
std::string file_content;
file_content.reserve(file_size);
char buffer[16384];
std::streamsize chars_read;
while (file.read(buffer, sizeof buffer), chars_read = file.gcount())
file_content.append(buffer, chars_read);
if (file.eof())
for (std::string::size_type offset = 0, found_at;
file_size > offset &&
(found_at = file_content.find(search_term, offset)) !=
std::string::npos;
offset = found_at + search_term_size)
std::cout << found_at << std::endl;
【讨论】:
@ildjarn: true(但是,在我的基准测试中,它的运行速度仍然是您的非增强解决方案的 两倍以上 ;-P) 很公平,我对您的结果进行了基准测试并验证了;我没想到从istreambuf_iterator
对复制这么慢。 :-[
@ildjarn:你的代码发生了什么?即使它不是最快的解决方案,它也可能是一个非常好的参考!我计划从所有 4 个解决方案中学习。
@ildjarn:zsero 是对的......你有很好的解决方案可以列出......这可能很简单,比如不在双端队列上使用保留 - 我没有时间调查 - 但这不是无论如何,它可能会在其他人/未来的库实现等中运行得更快......【参考方案2】:
这是完成第 1 部分的一种方式。我不确定我是否会将其描述为高质量,但可能是极简主义。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
std::ifstream ifs(argv[1], ios::binary);
std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
size_t pos = str.find(argv[2]);
if (pos != string::npos)
cout << "string found at position: " << int(pos) << endl;
else
cout << "could not find string" << endl;
return 0;
【讨论】:
谢谢,工作完美,读起来真的很不错!但我的问题是 std::string str (std::istreambuf_iterator, std::istreambuf_iterator) 非常慢。而实际搜索几乎不需要时间就能找到结果。有什么方法可以更快地创建字符串? @zsero - 迭代器很慢。更快的方法是 (1) 读取数据缓冲区并进行搜索,而不是将整个文件读入内存,所有这些都可能不是必需的; (2) 下拉到更多特定于操作系统的内容,如内存映射或使用操作系统提示,如 posix_fadvise。简单地使用一个好的缓冲区大小和 fstream.read() 会比这更快。以上是关于在二进制文件中搜索字符串的代码的主要内容,如果未能解决你的问题,请参考以下文章