在特定字段中搜索关键字后,从文本文件中提取多个记录

时间:2017-11-25 22:23:45

标签: c++ text full-text-search

我正在研究一些可以从文本文件中搜索故障单的代码。每张票以“***”开头,以“###”结尾。

(1)在“城市”字段中从用户输入中搜索关键字。 (2)一旦找到,就从该记录中返回所有记录和行,而不只是一个。

记录如下:

***
Ticket Number : 
First Name : T
First Name : C
Address of Violations : 123 Malberry Ln.
City : Oak Park //Need user to input City and Pull all tickets from that City
Plate : Q1234
Vin Number : V1234
Violation Narrative : NO PARKING
Violation Code :V1234
Violation Amount :50
Late Fee : 100
Make : 
Model : 
Was this Paid ? : 0
Date : 1012017
Time : 1200
Pay by Date : 1012018
Officer Number : 6630
###

我的查询必须针对每个类别。

例如,如果有三个记录,两个来自同一个城市“Oak Park”,我希望显示两个“Oak Park”记录,而不仅仅是一个。

我是如何开始这样做的,正在进行搜索,将记录从“***”拉到“###”可能是这样的:

{
ifstream in("tickets.txt");
string beforeEqual = "";
string afterEqual = "";
while (!in.eof())
{
    getline(in, beforeEqual, '***'); //grtting string upto =
    getline(in, afterEqual, '###'); //getting string after =
    cout << afterEqual << endl; //printing string after =
}

但我还需要搜索(“城市:”+ search_token)。

因此,当我进行(城市搜索)时,它会从该城市获取所有门票。

如何实施,我是否走上正轨?

到目前为止,我的工作只是一般搜索:

void city_search() {

string search;
string line;

ifstream inFile;
inFile.open("tickets.txt");

if (!inFile) {
    cout << "Unable to open file" << endl;
    exit(1);
}

cout << "Please enter a plate Number to search : " << endl;
cin >> search;

size_t pos;
while (inFile.good())
{
    getline(inFile, line); // get line from file
    pos = line.find(search); // search
    if (pos != string::npos) // string::npos is returned if string is not found
    {
        cout << search << "Found!";
        break;
    }
}

1 个答案:

答案 0 :(得分:0)

我认为你宁愿为他们制作一个通用的功能。如果我理解你最初的计划,那么在你描述的情况下,交换机意味着更多的开销。

你宁愿做的事情与此类似:

//This function compares the ticket's category's contents with the given string
std::string checkString(std::string stringToCheck) {
    std::string contentDelimiter = " : "; //Text after this will be read in
    std::string content = stringToCheck.substr(stringToCheck.find(contentDelimiter) + 
     contentDelimiter.length(), stringToCheck.length());
    //Find where the end of " : " is, read from there 'til end of line into "content"
    return content;
}

//This function opens the file, compares sought info to each relevant column,
//and types matching tickets out
void searchFile(const std::string& filePath, const int& amountOfCategories, 
                     const std::string& matchInfo, const int& categoryIndex) {
    int i = 0;
    std::string tempTicket[amountOfCategories]; 
    //Make a template to copy each ticket to for later use

    std::ifstream inFile;
    inFile.open(filePath.c_str());
    while (!inFile.eof()) { //Go through entire file
        std::getline(inFile, tempTicket[i]); //Put next line into the relevant slot
        i++;
        if (i == amountOfCategories) {
            if (matchInfo == checkString(tempTicket[categoryIndex]) {
                for (int j = 0; j < amountOfCategories; j++) { 
                         //If you want it to skip the *** and the ###, 
                         //you change it to this: int j = 1; j < amountOfCategories-1;
                    std::cout << tempTicket[j] << std::endl;
                }
                std::cout << std::endl;
            }
            i = 0;
        }
    }
    inFile.close();
}

此外,您还必须使函数查找类别索引,并在搜索正确的索引时循环查看类别的静态字符串数组。像这样:

//This outside of main obviously as an independent function
int position(const std::string& soughtCategory, 
                const std::string arr[], const int& amountOfCategories) {
    int found = -1;
    for (int i = 0; i<amountOfCategories; i++) {
        if (arr[i] == soughtCategory) {
            found = i;
        }
    }
    return found;
} 

//This in main:
int amountOfCategories = 10; //Or however many there will be(no duplicates)
std::string categories[amountOfCategories];
//categories[0] = "***";
//Place all of the others between these manually
//categories[9] = "###";

//Then call it like this, for example, in main:
searchFile("file.txt", amountOfCategories, "Tampa", position("City", categories, amountOfCategories));