私見では、パーサーにいくつかの状態がありません。ファイルがまだ有効で、整数を解析しているかどうかを確認する人もいます。
概念実証は次のとおりです。
#include <fstream>
#include <iostream>
#include <vector>
namespace {
void parse_integers(std::vector<int> & vi, std::string const & line) {
// Using strtol here - other tokenizers are possible.
char const * ip { line.c_str() };
char * ep;
do {
long int const v { strtol( ip, &ep, 10 ) };
vi.push_back( v );
ip = ep;
} while( *ep != '\0' );
}
}
int main() {
std::string inname { "source.txt" };
std::ifstream infile { inname };
if( ! infile ) {
std::cout << "There was a problem opening file "
<< inname << " for reading." << std::endl;
return 0;
};
enum class ParseState {
outer, found_integers, found_string
};
ParseState ps { ParseState::outer };
std::vector<int> s_integers;
std::string s_string;
while( infile ) {
std::string line;
getline( infile, line );
// Skip empty lines
if( line.size() == 0 ) {
continue;
}
if( line == "Integers:" ) {
ps = ParseState::found_integers;
continue;
} else if( line == "String:" ) {
ps = ParseState::found_string;
continue;
}
// Hope that a section was already found....
if( ps == ParseState::outer ) {
std::cerr << "Line with data but without a section found ["
<< line << "]" << std::endl;
continue;
}
switch( ps ) {
case ParseState::found_integers:
parse_integers(s_integers, line);
break;
case ParseState::found_string:
s_string += line + "\n";
break;
case ParseState::outer:
// Cannot happen
abort();
}
}
std::cout << "Dump file contents" << std::endl;
std::cout << "Strings: [" << s_string << "]" << std::endl;
std::cout << "Integers: ";
for(int i : s_integers) {
std::cout << "[" << i << "] ";
}
std::cout << std::endl;
return 0;
}
入力:
Integers:
1 2 3 4 56 111 761 777
String:
This is a string......
...(text).....
出力:
Dump file contents
Strings: [This is a string......
...(text).....
]
Integers: [1] [2] [3] [4] [56] [111] [761] [777]