Переписываю grep в C ++ - PullRequest
       15

Переписываю grep в C ++

1 голос
/ 13 марта 2012

Итак, я пытаюсь написать программу, которая выполняет ту же задачу, что и grep.В конце я хочу программу, которая принимает четыре аргумента, второй - что искать, третий - входной файл, а четвертый - выходной файл.Я думаю, что у меня есть хорошее представление о том, как это сделать, но, как обычно, теория проста и реальное программирование меня запутывает.В основном, где я сейчас нахожусь, у меня есть файл, и я пытаюсь найти его и получить все строки, которые содержат то, что я ищу, а также строку этого числа.

Я хочу использовать вектор для решения этой задачи.Я не совсем уверен, как это сделать.Будет ли проще пройти и добавить каждую строку к вектору по отдельности, а затем пройти и выбрать те, которые содержат желаемую строку в них, и использовать расположение массива в качестве номера строки?Я хотел бы думать, что есть способ только добавить те строки в вектор, которые содержат желаемую строку, но тогда я не уверен, как получить номер строки.Я начал пару раз, а затем стер то, что я понял, когда понял, что все неправильно.

Вот где я сейчас:

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

using namespace std;

int main (int argc, char* argv[]){

// validate the command line info
if( argc < 2 ) {
    cout << "Error: Incorrect number of command line arguments\n"
            "Usage: grep\n";
    return EXIT_FAILURE;
}

//Declare the arguments of the array
string query = argv[1]; 
string inputFileName = argv[2];
string outputFileName = argv [3];

// Validate that the file is there and open it
ifstream infile( inputFileName );
if( !infile ) {
    cout << "Error: failed to open <" << inputFileName << ">\n"
            "Check filename, path, or it doesn't exist.\n";
    return EXIT_FAILURE;
}

else{
vector<string> queries;


}

}

}

Ответы [ 2 ]

2 голосов
/ 13 марта 2012

Нет необходимости использовать вектор.Мне кажется, вы должны просто пройти по входному файлу по одной строке за раз, используя std :: getline, попытаться сопоставить каждый из них с регулярным выражением и вывести строки, которые сразу выполняются.

1 голос
/ 13 марта 2012

Большая сложность в реализации полного grep заключается в обработке десятков флагов для изменения его работы. Упрощенная версия, которая не пытается их поддерживать, а просто ищет набор файлов по указанному шаблону, может быть довольно простой. Версия C ++ 11 выглядит примерно так:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <regex>

class line {
    std::string data;
public:
    operator std::string() const { return data; }

    friend std::istream &operator>>(std::istream &is, line &l) {
        return std::getline(is, l.data);
    }
};

void process(std::regex const &pattern, std::istream &file) {
    typedef std::istream_iterator<line> in;
    typedef std::ostream_iterator<std::string> out;

    std::copy_if(in(file), 
                in(), 
                out(std::cout, "\n"), 
                [&](std::string const &s) {return std::regex_search(s, pattern);});
}

int main(int argc, char **argv) { 
    if (argc < 2) {
        std::cerr << "Usage: grep <pattern> [file specification]";
        return 1;
    }

    std::regex pattern(argv[1], std::regex::nosubs | std::regex::optimize);

    if (argc < 3)
        process(pattern, std::cin);
    else
        for (int i=2; i<argc; ++i) {
            std::ifstream infile(argv[i]);
            std::cout << "\t-- " << argv[i] << " --\n";
            process(pattern, infile);
        }
    return 0;
}

В Unix-подобных системах вам не нужно делать ничего особенного, чтобы построить это. В Windows вы захотите связать с предоставленным компилятором объектным файлом, который обрабатывает глобирование (например, setargv.obj, с MS VC ++).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...