酒店预订系统C++输入校验函数多版本错误求助
酒店预订系统输入校验函数问题修复
当前版本(输入回车后无法推进)
代码
int inputError(const std::string& output, int min, int max, const std::string& errortext) { int number = 0; bool error = false; do { std::cout << output; std::string input; std::getline(std::cin, input); try { size_t pos; numero = std::stoi(input, &pos); // 变量名错误:numero未定义,应为number if (pos != input.size()) { throw std::invalid_argument("Incorrect input."); } if (number < min || number > max) { throw std::out_of_range("Out of range"); } } catch (const std::invalid_argument& e) { error = true; std::cout << errortext << "\n"; } catch (const std::out_of_range& e) { error = true; std::cout << errortext << "\n"; } } while (error); return number; }
问题
输入空回车会触发错误,但后续输入正确内容后程序无法继续推进。核心原因是代码中使用了未定义的变量numero,而非声明的number,导致number始终为0,永远不满足范围校验。
示例错误输出:
Welcome. What would you like to do? 1: a 2: b 3: c 4: d 5: e Input wasn't found in the menu. Try again, please: 1: a 2: b 3: c 4: d 5: e 1 Input wasn't found in the menu. Try again, please: 0 1: a 2: b 3: c 4: d 5: e
旧版本1(含空格输入残留内容干扰后续操作)
代码
int inputError(const std::string& output, int min, int max, const std::string& errorText) { int number = 0; bool error; do { error = false; std::cout << output; std::string input; std::cin >> input; std::istringstream iss(input); if (!(iss >> number) || number > max || number < min || iss.peek() != EOF) { error = true; std::cout << errorText << "\n"; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } } while (error); return number; }
问题
使用std::cin >> input读取输入时,会自动跳过前导空格并在遇到空格时停止读取。输入如"1 5"这类内容时,只会读取"1",剩余的"5"会留在输入缓冲区,被当作下一次输入的内容,导致后续校验错误。
旧版本2(多空格数字导致提前推进)
代码
int inputError(const std::string& output, int min, int max, const std::string& errorText) { int number = 0; bool error; do { error = false; std::cout << output; std::string input; std::getline(cin, input); // 缺少std::命名空间 std::istringstream iss(input); if (!(iss >> number) || number > max || number < min || iss.peek() != EOF) { error = true; std::cout << errorText << "\n"; std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } } while (error); return number; }
问题
输入如"1 1"这类包含大量空格加额外数字的内容时,iss.peek() != EOF会触发错误,但错误处理中调用了std::cin.ignore()。此时getline已经读取了整行输入,ignore()会直接读取下一行输入,导致程序提前推进两次。
修正后的输入校验函数
#include <iostream> #include <string> #include <stdexcept> #include <limits> #include <cctype> int inputError(const std::string& output, int min, int max, const std::string& errortext) { int number = 0; bool error; do { error = false; std::cout << output; std::string input; // 读取整行输入,确保获取用户的完整输入 if (!std::getline(std::cin, input)) { // 处理输入流异常 std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); error = true; std::cout << errortext << "\n"; continue; } try { size_t convert_pos; // 转换字符串为整数,自动跳过前导空格 number = std::stoi(input, &convert_pos); // 跳过转换后的所有空格 size_t remaining_pos = convert_pos; while (remaining_pos < input.size() && std::isspace(static_cast<unsigned char>(input[remaining_pos]))) { ++remaining_pos; } // 检查是否还有非空格字符 if (remaining_pos != input.size()) { throw std::invalid_argument("Invalid characters after number"); } // 检查数字是否在指定范围内 if (number < min || number > max) { throw std::out_of_range("Number out of range"); } } catch (const std::invalid_argument&) { error = true; std::cout << errortext << "\n"; } catch (const std::out_of_range&) { error = true; std::cout << errortext << "\n"; } } while (error); return number; }
关键修正点
- 修复变量名错误:将当前版本中的
numero改为number,确保变量正确赋值 - 完整读取整行输入:使用
std::getline读取用户全部输入,避免残留内容干扰后续操作 - 兼容前后空格:允许输入前后存在空格,仅校验数字部分和是否有多余非空格字符
- 正确处理输入流异常:捕获
getline的失败状态,重置输入流并清空缓冲区 - 移除不必要的ignore操作:
getline已读取整行,无需额外忽略字符,避免提前消耗下一行输入
内容的提问来源于stack exchange,提问作者Riku Hakamaki
相关产品推荐
相关产品推荐

