C++学习 | 通过正则表达式保证输入格式的正确性
——仅记录个人学习过程——
如果题目中提出了“读入特定输入格式的数据,如果不符合要求则抛出异常、输出错误提示、结束程序”的要求,使用C++的普通输入流无法解决。我使用的方法是逐行读入、结合正则表达式。
题目要求:
从input.txt文件中读入以下内容
首先输入一个正整数n,表示接下来输入的数据总行数。
输入n行数据,每行形如"C 0 1 3"或“L 2 3 5 3”或“S 3 6 4 1”(字符‘C‘后跟三个整数,或字符‘L‘、‘S‘后跟四个整数),如果输入格式不对,或是输入行数过多或过少,则抛出相应异常。
#include <fstream> #include <sstream> #include <string> #include <regex> const regex Nregex("\\s*(0|([1-9][0-9]*))\\s*"); //首行的n const regex ENDregex("\\s*"); //文件末尾的空白 const regex THREEregex("(\\s+-?(0|([1-9][0-9]*))){3}\\s*"); //三个整数 const regex FOURregex("(\\s+-?(0|([1-9][0-9]*))){4}\\s*"); //四个整数 ifstream input; input.open("input.txt", ios::in); int n; stringstream inputLineStream; string nString; getline(input, nString); if (!regex_match(nString, Nregex)) { //未匹配到文件开始的n,此处的处理操作省略 } n = stoi(nString); //字符串转整数 for (int i = 0; i < n; i++) { inputLineStream.clear(); string newInputLine; string kind; input >> kind; if (!kind.compare("L") || !kind.compare("S")) { getline(input, newInputLine); if (!regex_match(newInputLine, FOURregex)) { //输入不是四个整数,此处的处理操作省略 } inputLineStream << newInputLine; inputLineStream >> int1 >> int2 >> int3 >> int4; //具体处理省略,从这个stream中可以读出这四个整数 } else if (!kind.compare("C")) { getline(input, newInputLine); if (!regex_match(newInputLine, THREEregex)) { //输入不是三个整数,此处的处理操作省略 } inputLineStream << newInputLine; inputLineStream >> int1 >> int2 >> int3; //具体处理省略,从这个stream中可以读出这四个整数 } else { //读入的并非"C"、"L"、"S",格式显然错误 } } string testEndString; getline(input, testEndString); if (!regex_match(testEndString, ENDregex)) { //输入未结束,此处的处理操作省略 } input.close();