Заставить getline проверить вторую и третью строку входного файла - PullRequest
1 голос
/ 26 марта 2019

Я проверил большинство вопросов stackoverflow по этой теме, но, похоже, не получил правильного ответа.

Я читаю строки из txt-файла, затем проверяю, есть ли в каждой строке txt-файлаправильные строки с использованием регулярных выражений.

Мой код проверяет первую строку входного файла и выводит «bad», если первая строка входного файла не «#FIRST».Я пытаюсь сделать то же самое для следующих двух строк, однако я не знаю, как заставить getline проверять только вторую строку после того, как первая строка в порядке.

Вторая строка должна быть "этокомментарий".Третья строка должна быть "#SECOND".

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

int main (){



    std::ifstream input( "test.txt" );
    for( std::string line; getline( input, line ); )
{   std::regex e("#FIRST");
  std::regex b("#this is a comment");
   //std::regex c("#SECOND");

    if(std::regex_match(line,e))
    std::cout << "good." << std::endl;

else
  std::cout << "bad." << std::endl;

    if(std::regex_match(line,b))
    std::cout << "good." << std::endl;

else
  std::cout << "bad." << std::endl;
break;

}

    return 0;
}

входной файл

#FIRST
#this is a comment
#SECOND

1 Ответ

0 голосов
/ 26 марта 2019

Одним из решений является сохранение списка проверок, которые вы хотите сделать, а затем циклическое их выполнение.Для каждой проверки прочитайте строку и посмотрите, соответствует ли она:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    std::vector<std::string> validLines {
        "#FIRST",
        "this is a comment",
        "#SECOND"
    };

    std::istringstream fileStream { // pretend it's a file!
            "#FIRST\n" \
            "this is a comment\n" \
            "this line should fail\n"};

    std::string fileLine;
    for (auto const& validLine : validLines) {
        // for every validity check, read a line from the file and check it
        if (!std::getline(fileStream, fileLine)) {
            std::cerr << "Failed to read from file!\n";
            return 1;
        }
        if (validLine == fileLine) { // could be a regex check
            std::cout << "good\n";
        }
        else {
            std::cout << "bad\n";
        }
    }
}

Это будет читать только те строки, для которых у вас есть проверка.Если в файле будет больше строк, они вообще не будут прочитаны.

Также обратите внимание, я сделал несколько упрощений, используя строку вместо файла и используя простое совпадение вместорегулярное выражение, но это не имеет никакого значения для бит, который вам небезразличен.


Просто для удовольствия, вот другой подход, если вам нужно только проверить определенные номера строк:

#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>

int main()
{
    using LineCheckMap = std::unordered_map<std::size_t, std::string>;
    LineCheckMap validLines {
        {3, "#SECOND"}
    };

    std::istringstream fileStream { // pretend it's a file!
            "#FIRST\n" \
            "this is a comment\n" \
            "this line should fail\n"};

    std::string fileLine;
    std::size_t lineCount {0};
    while (std::getline(fileStream, fileLine)) {
        // for every line in the file, add to a counter and check
        // if there is a rule for that line
        ++lineCount;
        LineCheckMap::const_iterator checkIter = validLines.find(lineCount);
        if (std::end(validLines) != checkIter) {
            if (checkIter->second == fileLine) {
                std::cout << "good\n";
            }
            else {
                std::cout << "bad\n";
            }
        }
    }
}
...