You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用vector列表查找文件指定单词实例?代码优化求助

文件多单词搜索函数优化方案

问题描述

需要实现函数查找文件中用户指定单词列表的所有实例:输入如Breaking-Bad或Lilo-Stitch会被拆分为vector<string>中的[breaking, bad]、[lilo, stitch],但当前searchfile函数仅能找到vector首个索引的单词,后续单词无输出。目标是找出文件中包含指定单词列表中一个或全部单词的所有行。

问题代码

原搜索函数:

int searchfile(fstream& file, vector<string>& UserSearch, int counter)
{
    string input;
    int amount = 0;
    int line = 0;
    for (int i = 0; i < counter; i++) {
        while (getline(file, input))
        {
            line++;

            if (input.find(UserSearch[i], 0) != string::npos)
            {
                cout << "found " << UserSearch[i] << " in line " << line << endl;
                amount++;
            }

        }
    }
    return amount;
}

主函数尝试的调用方式:

for (int i = 0; i < list.size; i++) {
searchFile(infile, list, counter);
}

问题原因

  1. 文件指针位置问题:第一次循环读取单词时,getline会把文件读到末尾,后续循环中文件指针已处于EOF位置,getline直接返回false,不再读取任何行,导致后续单词无法匹配。
  2. 遍历逻辑错误:原代码先遍历单词再遍历行,而非先遍历行再检查所有单词,既低效又导致文件重复读取的问题。

优化方案

方案1:逐行检查所有单词(匹配任意一个单词就输出)

重新调整遍历顺序:先读取每一行,再对该行检查所有目标单词,这样只需遍历文件一次,同时解决文件指针问题。

优化后的函数代码:

#include <fstream>
#include <vector>
#include <string>
#include <iostream>

int searchfile(std::fstream& file, std::vector<std::string>& UserSearch)
{
    std::string input;
    int totalMatches = 0;
    int lineNum = 0;

    // 重置文件指针到开头,避免之前读取过导致的EOF问题
    file.clear();
    file.seekg(0, std::ios::beg);

    while (std::getline(file, input))
    {
        lineNum++;

        for (const auto& word : UserSearch)
        {
            if (input.find(word, 0) != std::string::npos)
            {
                std::cout << "找到单词 \"" << word << "\" 在第 " << lineNum << " 行" << std::endl;
                totalMatches++;
                // 若只需标记该行有匹配、不需要输出每个单词的匹配,可在此处break
            }
        }
    }

    return totalMatches;
}

方案2:查找包含所有指定单词的行

如果需求是找出同时包含所有单词的行,修改行内检查逻辑即可:

int searchfileAllWords(std::fstream& file, std::vector<std::string>& UserSearch)
{
    std::string input;
    int totalMatches = 0;
    int lineNum = 0;

    file.clear();
    file.seekg(0, std::ios::beg);

    while (std::getline(file, input))
    {
        lineNum++;
        bool allWordsFound = true;

        for (const auto& word : UserSearch)
        {
            if (input.find(word, 0) == std::string::npos)
            {
                allWordsFound = false;
                break;
            }
        }

        if (allWordsFound)
        {
            std::cout << "第 " << lineNum << " 行包含所有指定单词" << std::endl;
            totalMatches++;
        }
    }

    return totalMatches;
}

主函数正确调用方式

调用时无需循环,直接传入整个单词列表即可,同时确保文件处于打开状态:

int main()
{
    std::fstream infile("your_file.txt", std::ios::in);
    if (!infile.is_open())
    {
        std::cerr << "无法打开文件" << std::endl;
        return 1;
    }

    std::vector<std::string> searchList = {"breaking", "bad"};
    int matchCount = searchfile(infile, searchList);
    // 如果需要查找包含所有单词的行:
    // int matchCount = searchfileAllWords(infile, searchList);

    std::cout << "总匹配次数:" << matchCount << std::endl;

    infile.close();
    return 0;
}

关键改进点

  • 调整遍历顺序:先逐行读取,再检查该行所有单词,仅遍历文件一次,提升效率。
  • 重置文件指针:每次调用函数时先重置文件到开头,避免之前的读取操作导致的EOF问题。
  • 灵活适配需求:提供了“匹配任意单词”和“匹配所有单词”两种实现,根据实际需求选择。

内容的提问来源于stack exchange,提问作者UniqulyDumb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:50:20