Как использовать stringstream в то время как логика цикла для всего текстового файла в C ++ - PullRequest
0 голосов
/ 25 октября 2019

Следующие ссылки, которые я использовал, помогли приблизиться к решению, однако я все еще испытываю ошибки чтения, памяти или зацикливания. Я перебираю лог-файл и извлекаю json. Перед запуском объектов json есть дата и время вместе с сообщением и идентификатором объекта, что соответствует json. Так что оба необходимы. Время также является фактором по мере роста файла журнала. Мне нужна помощь, чтобы выяснить, где я иду не так.

https://riptutorial.com/cplusplus/example/19029/string-streams

Регулярное выражение Multilines в C ++

https://www.codeproject.com/Questions/1221494/Simple-multiline-regex-in-Cplusplus

http://www.cplusplus.com/reference/iterator/next/

Stringstream c ++, в то время как цикл

Я могу использовать регулярные выражения в строке без проблем, и в качестве многострочного. Чтение из файла с использованием stringstream У меня есть while(input >> sstr.rdbuf());, где мой поток теперь буферизован для моего понимания.

когда я cout << sstr.str() читается только 1 раз

std::ifstream input("log.txt");
std::stringstream sstr;
std::smatch m;
std::regex reg("(\\{|\\[)(\\n\\s+.*)+\\n*(\\}||\\])"); 

while (input >> sstr.rdbuf());

std::string strang = sstr.str();
while (std::regex_search(strang, m, reg)) {
    std::cout << "Results : \n" << m.str() << '\n';
    for (i = 0; i < strang.length(); i++) {
        std::cout << m.str(i);
        i++;
    }
}

Кажется, что файл зацикливается вечно, если файл маленький. Для больших файлов 30MB + нет вывода.

Я смотрю на векторы и хеш-карты, но я не уверен, как применить регулярное выражение к hashmap - кажется странным. Кроме того, я узнал, что векторы в любом случае хранят до 30 переменных, так что этот тип нагрузки слишком велик.

Спасибо!

Другая вариация

void PrintMatches(std::string str, std::regex reg) { 
    std::smatch matches;
    std::cout << matches.size() << std::endl;

}
int main() {
    std::ifstream input("log.txt");
    std::stringstream sstr;
    std::smatch m;
    std::regex reg("(\\{|\\[)(\\n\\s+.*)+\\n*(\\}||\\])");

    while (input >> sstr.rdbuf());

    std::string str = sstr.str();
    std::cout << str;
    //PrintMatches(str, reg);

    return 0;
}


1 Ответ

0 голосов
/ 25 октября 2019

while (input >> sstr.rdbuf()); не имеет смысла. operator>> на streambuf выпадает в одном действии, или оно не выполняется. Если произойдет сбой, он почти наверняка не будет успешным независимо от того, сколько раз вы повторите попытку, и, по крайней мере, некоторые из этих режимов сбоя (например, сбой вставки в выходную последовательность) не изменит «правдивость» istream,таким образом, цикл станет бесконечным (что потенциально может объяснить, почему вы не видите вывод для больших файлов, хотя было бы странным, если бы не выплескивался сбой на файлах такого маленького размера). Взгляните на эффективную (если, возможно, немного чрезмерно компактную) реализацию с сохранением файла (которая позволит избежать хотя бы одной ненужной копии, необходимой вашему коду).

Другая проблема:

strang ==sstr.str();

, который сравнивает пустую строку с временной, а затем отбрасывает результат;предположительно, вы хотели:

strang = sstr.str();

Кроме того, этот цикл никогда не запускается:

for (i = 0; i > strang.length(); i++) {

При тестировании i > strang.length(), i всегда 0 в первом тесте и strang всегда будет больше или равно ей, поэтому внутренний цикл никогда не запускается.

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

Наконец, ваш while (std::regex_search(strang, m, reg)) { никогда не изменится strang, m или reg;он либо никогда не будет работать, либо будет работать вечно.

...