实现 grep 命令,grep 命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。比如有以下文本: #test.txt

ababdnskahcpk

kcnwdklanabdc

kksnsacdkjkaha

.........

执行- grep “abd” test.txt 则执行的结果就是打印输出前两行的内容: ababdnskahcpk kcnwdklanabdc

从磁盘中读取文件,并能实现带参数的 grep 命令,grep -n -nNum,grep -n 是将搜 索出来的文本结果标上行号;grep -nNum 是进行行数的限制,例如 grep -1 “abd” test.txt,那么上面文本搜索的结果就只有第一行 ababdnskahcpk。

思路:

设计一个结构体lines用来存储文件数据的行号line和内容word,用向量words来存储结构体,

打开文件,按行读取,存到向量中,根据接收的参数进行grep,利用kmp算法进行内容的匹配

具体代码:

#include<iostream>
#include<string>
#include<vector>
#include<fstream>
using namespace std;
typedef struct lines{
    int line;
    string word;
}lines;
//字符串匹配 next数组和kmp算法
int Next[100];//next数组next是关键字,不要用这个名字
void getnext(string t){
    int j=-1;
    int i=0;
    Next[0]=-1;
    while(i<t.size()){
        if(j==-1||t[i]==t[j]){
            j++;
            i++;
            Next[i]=j;
        }else{
            j=Next[j];
        }
    }
}
int KMP(string s,string t){
    getnext(t);
    int i=0,j=0;
    int slen=s.size();
    int tlen=t.size();
    while(i<slen&&j<tlen){
        if(j==-1||s[i]==t[j]){
            j++;
            i++;
        }else{
            j=Next[j];
        }
    }
    if(j==tlen)
        return i-j+1;
    else
        return 0;
}
//带参数的grep(参数,模式,内容)
void grep(char argv[],string p,vector<lines> words){
    if(argv[1]!='n'){
        int limit=(int)argv[1]-48;
        //cout<<limit<<endl;
        for(int i=0;i<words.size();i++){
            if(limit==0)break;
            if(KMP(words[i].word,p)!=0){
                cout<<words[i].word<<endl;
                limit--;
            }
        }
    }
    else{
        for(int i=0;i<words.size();i++){
        if(KMP(words[i].word,p)!=0){
        cout<<words[i].line<<" "<<words[i].word<<endl;
        }
    }
    }
}
int main() {
    string op,patten;//patten 要查找的模式串
    char filename[100];
    char argv[2];
    cin>>op>>argv>>patten>>filename;
    //string p="abd";
    ifstream r;
    r.open(filename,ios::binary);//读文件
    vector<lines> words;
    int c=0;
    string str;
    while(getline(r,str)){
        c++;
        lines w;
        w.line=c;
        w.word=str;
        words.push_back(w);
    }
    grep(argv,patten,words);
    r.close();
    return 0;
}

执行结果

带行号输出

限制输出条数

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐