使用用户输入时regex_search报错,正则提取二次方程系数异常
问题根源
你的正则表达式没有正确设置捕获组来单独提取数字系数,反而捕获了包含变量和符号的完整项(如3x^2)。当你把这种包含非数字字符的字符串传给stoi时,自然会触发std::invalid_argument异常——因为stoi只能解析纯数字组成的字符串。
解决方案
核心思路是调整正则表达式,为每个系数单独设置捕获组,只捕获数字部分,同时处理系数省略(如x^2等价于1x^2,-x等价于-1x)的特殊情况。
1. 修正正则表达式
针对二次方程的三个部分(二次项、一次项、常数项),分别设置捕获组:
- 二次项:匹配
([+-]?\d*)x\^2,其中([+-]?\d*)专门捕获系数数字,允许正负号和空值(对应系数为1/-1的情况) - 一次项:匹配
([+-]?\d*)x,逻辑同二次项 - 常数项:匹配
([+-]?\d+),捕获纯数字常数
2. 处理捕获结果的特殊情况
当捕获组为空或仅为正负号时,需要手动赋值:
- 若二次项捕获组为空(比如输入
x^2+3x+1),系数为1 - 若二次项捕获组为
-(比如输入-x^2+3x+1),系数为-1 - 一次项的逻辑和二次项一致,常数项为空时系数为
0
示例代码(C++)
#include <iostream> #include <regex> #include <string> using namespace std; int main() { string input; cout << "输入二次方程(格式示例:3x^2+5x-2=0 或 x^2-3x+5):"; getline(cin, input); // 移除等号及右侧内容(如果存在) size_t eq_pos = input.find('='); if (eq_pos != string::npos) { input = input.substr(0, eq_pos); } // 正则表达式:匹配二次项、一次项、常数项的系数捕获组 regex eq_regex(R"(([+-]?\d*)x\^2)?([+-]?\d*)x?([+-]?\d+)?)"); smatch match_results; if (regex_match(input, match_results)) { // 处理二次项系数a string a_str = match_results[1].str(); int a = 1; if (!a_str.empty()) { a = (a_str == "+") ? 1 : (a_str == "-") ? -1 : stoi(a_str); } // 处理一次项系数b string b_str = match_results[2].str(); int b = 0; if (!b_str.empty()) { b = (b_str == "+") ? 1 : (b_str == "-") ? -1 : stoi(b_str); } // 处理常数项系数c string c_str = match_results[3].str(); int c = 0; if (!c_str.empty()) { c = stoi(c_str); } // 计算判别式 int discriminant = b * b - 4 * a * c; cout << "二次项系数a:" << a << endl; cout << "一次项系数b:" << b << endl; cout << "常数项系数c:" << c << endl; cout << "判别式Δ:" << discriminant << endl; } else { cout << "输入格式不符合要求,请检查后重试。" << endl; } return 0; }
额外注意事项
- 确保输入格式相对规范,比如不要出现空格(若需要支持空格,可在正则中加入
\s*匹配空白字符) - 若需要支持更复杂的输入(如一次项在常数项之后、系数为小数等),可以进一步扩展正则表达式和类型转换逻辑(比如用
stod代替stoi)
内容的提问来源于stack exchange,提问作者Ichiro
相关产品推荐
相关产品推荐

