TextQuery

作者: 奇点创客 | 来源:发表于2022-10-23 11:13 被阅读0次

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";
}

相关文章

  • TextQuery

    C++ Primer 文本查询程序 运行效果 源码

  • 简单的文件查询

    C++ Primer 中的textquery例子 要求 从文本读取数据并构建查询表 返回查询结果 分析查询操作 支...

网友评论

      本文标题:TextQuery

      本文链接:https://www.haomeiwen.com/subject/dajizrtx.html