You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

酒店预订系统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;
}

关键修正点

  1. 修复变量名错误:将当前版本中的numero改为number,确保变量正确赋值
  2. 完整读取整行输入:使用std::getline读取用户全部输入,避免残留内容干扰后续操作
  3. 兼容前后空格:允许输入前后存在空格,仅校验数字部分和是否有多余非空格字符
  4. 正确处理输入流异常:捕获getline的失败状态,重置输入流并清空缓冲区
  5. 移除不必要的ignore操作:getline已读取整行,无需额外忽略字符,避免提前消耗下一行输入

内容的提问来源于stack exchange,提问作者Riku Hakamaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:10:58