I have checked most stackoverflow questions regarding this topic but I don't seem to get the correct answer.
I am reading the strings from a txt file then I check if each line of the txt file has the correct strings using regex.
My code checks the first line of the input file and print's out "bad" if the first line of the input file is not "#FIRST". I am trying to do the same for the next two lines ,however I don't know how to tell getline to only check the second line after the first line is ok.
The second line should be "this is a comment". The third line should be"#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;
}
input file
#FIRST
#this is a comment
#SECOND
One solution is to store a list of the checks you want to make, then loop through them. For each check, read a line and see if it matches:
#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";
}
}
}
This will only read lines that you have a check for though. If there are more lines in the file, they won't get read at all.
Also note, I made a couple of simplifications, using a string instead of a file, and using a simple match instead of a regex, but that doesn't make any difference to the bit you care about.
Just for fun, here's another approach if you only need to check certain line numbers:
#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";
}
}
}
}