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();