Программирование. Принципы и практика использования C++ Исправленное издание, стр. 328
Мы не можем проверить, что знак табуляции действительно является таковым, но в данном случае он раскрывается в ходе набора текста и распознается сам.
Приступим к самой интересной части упражнения: к шаблону для строк, из которых мы хотим извлекать числовые данные. Первое поле вновь имеет шаблон
^[\w]+\d+^[\w ]+( \d+)(\d+)(\d+)$После его вставки в строковый литерал он превращается в такую строку:
"^[\\w ]+(\\d+)(\\d+)(\\d+)$"Теперь мы сделали все, что требовалось. Сначала проверим, правильно ли сформирована таблица.
int main(){ ifstream in("table.txt"); // входной файл if (!in) error("Нет входного файла\n"); string line; // буфер ввода int lineno = 0; regex header( "^[\\w ]+( [\\w ]+)*$"); // строка заголовка regex row("^[\\w]+(\\d+)(\\d+)(\\d+)$"); // строка данных if (getline(in,line)) { // проверяем строку заголовка smatch matches; if (!regex_match(line,matches,header)) error("Нет заголовка"); } while (getline(in,line)) { // проверяем строку данных ++lineno; smatch matches; if (!regex_match(line,matches,row)) error("неправильная строка",to_string(lineno)); }}Для краткости мы не привели здесь директивы
#includeregex_match()regex_search()regex_match()regex_search()regex_match()regex_search()Теперь можем перейти к верификации данных в таблице. Мы подсчитаем количество мальчиков (“drenge”) и девочек (“piger”), учащихся в школе. Для каждой строки мы проверим, действительно ли в последнем поле (“ELEVER IALT”) записана сумму первых двух полей. Последняя строка (“Alle klasser”) содержит суммы по столбцам. Для проверки этого факта модифицируем выражение row, чтобы текстовое поле содержало частичное совпадение и можно было распознать строку “Alle klasser”.
int main(){ ifstream in("table.txt"); // входной файл if (!in) error("Нет входного файла"); string line; // буфер ввода int lineno = 0; regex header( "^[\\w ]+( [\\w ]+)*$"); regex row("^([\\w ]+)(\\d+)(\\d+)( \d+)$"); if (getline(in,line)) { // проверяем строку заголовка boost::smatch matches; if (!boost::regex_match(line, matches, header)) { error("Нет заголовка"); } }// суммы по столбцам: int boys = 0; int girls = 0; while (getline(in,line)) { ++lineno; smatch matches; if (!regex_match(line, matches, row)) cerr << "Неправильная строка: " << lineno << '\n'; if (in.eof()) cout << "Конец файла\n"; // проверяем строку: int curr_boy = from_string<int>(matches[2]); int curr_girl = from_string<int>(matches[3]); int curr_total = from_string<int>(matches[4]); if (curr_boy+curr_girl != curr_total) error("Неправильная сумма\n"); if (matches[1]=="Alle klasser") { // последняя строка if (curr_boy != boys) error("Количество мальчиков не сходится\n"); if (curr_girl != girls) error("Количество девочек не сходится\n"); if (!(in>>ws).eof()) error("Символы после итоговой строки"); return 0; } // обновляем суммы: boys += curr_boy;