如何在二进制文件中查找字符串?

时间:2019-05-07 19:09:05

标签: c++ file binary-data

我想在二进制文件中找到特定的字符串“ fileSize”。
查找该字符串的目的是获得字符串旁边的4个字节,因为这4个字节包含我要读取的数据大小。

二进制文件的内容如下:

同一字符串在另一个位置:

另一个位置:

以下是将数据写入文件的功能:

void W_Data(char *readableFile, char *writableFile) {
    ifstream RFile(readableFile, ios::binary);
    ofstream WFile(writableFile, ios::binary | ios::app);

    RFile.seekg(0, ios::end);
    unsigned long size = (unsigned long)RFile.tellg();
    RFile.seekg(0, ios::beg);

    unsigned int bufferSize = 1024;
    char *contentsBuffer = new char[bufferSize];

    WFile.write("fileSize:", 9);
    WFile.write((char*)&size, sizeof(unsigned long));
    while (!RFile.eof()) {
        RFile.read(contentsBuffer, bufferSize);
        WFile.write(contentsBuffer, bufferSize); 
    }
    RFile.close();
    WFile.close();
    delete contentsBuffer;
    contentsBuffer = NULL;
}

另外,搜索字符串的函数:

void R_Data(char *readableFile) {
    ifstream RFile(readableFile, ios::binary);

    const unsigned int bufferSize = 9;

    char fileSize[bufferSize];
    while (RFile.read(fileSize, bufferSize)) {
        if (strcmp(fileSize, "fileSize:") == 0) {
            cout << "Exists" << endl;
        }
    }
    RFile.close();
}

如何在二进制文件中找到特定的字符串?

2 个答案:

答案 0 :(得分:2)

我认为使用find()是搜索模式的简便方法。

void R_Data(const std::string filename, const std::string pattern) {
    std::ifstream(filename, std::ios::binary);
    char buffer[1024];

    while (file.read(buffer, 1024)) {
        std::string temp(buffer, 1024);
        std::size_t pos = 0, old = 0;

        while (pos != std::string::npos) {
            pos = temp.find(pattern, old);
            old = pos + pattern.length();
            if ( pos != std::string::npos )
                std::cout << "Exists" << std::endl;
        }
        file.seekg(pattern.length()-1, std::ios::cur);
    }
}

答案 1 :(得分:1)

  

如何在二进制文件中找到特定的字符串?

如果您不知道字符串在文件中的位置,建议您执行以下操作:

  1. 查找文件的大小。
  2. 分配内存以便能够读取文件中的所有内容。
  3. 读取从文件到分配的内存的所有内容。
  4. 遍历文件的内容,然后使用std::strcmp / std::strncmp查找字符串。
  5. 使用完内存后,请重新分配内存。

使用中有几个问题

const unsigned int bufferSize = 9;

char fileSize[bufferSize];
while (RFile.read(fileSize, bufferSize)) {
    if (strcmp(fileSize, "filesize:") == 0) {
        cout << "Exists" << endl;
    }
}

问题1

strcmp实际上包含字符串fileSize时,"fileSize:"行将导致未定义的行为,因为变量仅具有9个字符的足够空间。它需要一个附加元素来保存终止的空字符。您可以使用

const unsigned int bufferSize = 9;

char fileSize[bufferSize+1] = {0};
while (RFile.read(fileSize, bufferSize)) {
    if (strcmp(fileSize, "filesize:") == 0) {
        cout << "Exists" << endl;
    }
}

解决这个问题。

问题2

您正在以9的块为单位读取文件的内容。

第一次调用RFile.read会读取第一个9个字符的块。
第二次调用RFile.read将读取第二个9个字符的块。
第三次调用RFile.read将读取第三个9个字符的块。等

因此,除非字符串"fileSize:"位于一个这样的块的边界,否则测试

if (strcmp(fileSize, "filesize:") == 0)

永远不会过去。