TextQuery

C++ Primer 文本查詢程序

運行效果
源碼
#include <iostream>
#include <vector>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <memory>
#include <sstream>
#include <format>
#include <iomanip>
#include <Windows.h>

using line_no = std::vector<std::string>::size_type;

class QueryResult
{
    friend std::ostream& operator<<(std::ostream&, const QueryResult&);
public:
    QueryResult(std::string s,
                std::shared_ptr<std::set<line_no>> p,
                std::shared_ptr<std::vector<std::string>> f) :
        sought(s), lines(p), file(f)
    {}
private:
    std::string sought; // 要查詢的單詞
    std::shared_ptr<std::set<line_no>> lines;
    std::shared_ptr<std::vector<std::string>> file;
};

std::string make_plural(size_t ctr, const std::string& word, const std::string& ending)
{
    return (ctr > 1) ? word + ending : word;
}

void print_line(const std::string& line, const std::string& target)
{
    auto add_background_color = [](const std::string& word) {
        HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
        WORD wOldColorAttrs;
        CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

        // Get the current color
        GetConsoleScreenBufferInfo(h, &csbiInfo);
        wOldColorAttrs = csbiInfo.wAttributes;

        // Set the new color
        SetConsoleTextAttribute(h, FOREGROUND_GREEN | BACKGROUND_RED);
        std::cout << word;

        // Restore the original color
        SetConsoleTextAttribute(h, wOldColorAttrs);
    };

    std::istringstream ss(line);
    std::string word;
    while (ss >> word) {
        if (word == target) add_background_color(word);
        else std::cout << word;
        std::cout << " ";
    }
}

std::ostream& operator<<(std::ostream& os, const QueryResult& qr)
{
    os << std::quoted(qr.sought) << " occurs " << qr.lines->size() << " "
       << make_plural(qr.lines->size(), "time", "s") << " : \n";

    const auto num_width = std::to_string(qr.file->size()).size();
    for (const auto num : *qr.lines) {
        os << std::format("\t(line {:>{}}) ", num + 1, num_width);
        print_line((*qr.file)[num], qr.sought);
        os << "\n";
    }
    return os;
}

class TextQuery {
public:
    TextQuery(std::ifstream&);
    QueryResult query(const std::string&) const;
private:
    std::shared_ptr<std::vector<std::string>> file;
    std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;
};

TextQuery::TextQuery(std::ifstream& is) :
    file(new std::vector<std::string>)
{
    std::string text; // 每行
    while (std::getline(is, text)) {
        file->push_back(text);
        auto n = file->size() - 1;
        std::istringstream line(text);
        std::string word;
        while (line >> word) {
            auto& line_nos = wm[word];
            if (!line_nos) line_nos.reset(new std::set<line_no>);
            line_nos->insert(n);
        }
    }
}

QueryResult TextQuery::query(const std::string& sought) const
{
    static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);
    auto loc = wm.find(sought);
    if (loc == wm.end()) return QueryResult(sought, nodata, file); 
    return QueryResult(sought, loc->second, file);
}


void runQueries(std::ifstream& infile)
{
    TextQuery tq(infile);
    while (true) {
        std::cout << "Enter word to look for, or q to quit: ";
        std::string word;
        if (!(std::cin >> word) || word == "q") break;
        std::cout << tq.query(word) << std::endl;
    }
}

int main()
{
    const std::string filename{R"(E:\Desktop\text.txt)"};
    std::ifstream file(filename);
    if (file.is_open())
        runQueries(file);
    else
        std::cerr << "open file failed!\n";
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容