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

C++多枚举输入获取与校验的代码优化方案咨询

优化多枚举设置项的用户输入逻辑(消除重复代码)

问题描述

我需要处理多个作为程序设置项的枚举类型,要求逐个获取用户输入,且针对每个设置项持续请求直到输入合法,但当前实现存在大量重复代码,有没有更优的实现方式?

原代码

#include <iostream>
#include <limits>

enum Input1 {Type1 = 1, Type2 = 2, Type3 = 3, Type4 = 4};
enum Input2 {Type11 = 5, Type22 = 17};

bool validate_input(Input1 input1, Input2 input2 = Type11) {
  if(input1 != Type1 && input1 != Type2 && input1 != Type3 && input1 != Type4) {
    return false;
  }
  
  if(input2 != Type11 && input2 != Type22) {
    return false;
  }
  
  return true;
}

int main()
{
  int iInput1, iInput2, iInput3;
  Input1 eInput1;
  Input2 eInput2;
  bool return_val;
  
  do {
    std::cout << "Select option: 1. 2. 3. 4.";
    std::cin >> iInput1;

    if (std::cin.fail()) {
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    eInput1 = (Input1) iInput1;

    return_val = validate_input(eInput1);
    if (!return_val) {
      std::cout << "Invalid input!\n";
    }
  } while (!return_val);
  
  do {
    std::cout << "Select option: 1. 2.";
    std::cin >> iInput2;

    if (std::cin.fail()) {
      std::cin.clear();
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    }

    eInput2 = (Input2) iInput2;

    return_val = validate_input(eInput1, eInput2);
    if (!return_val) {
      std::cout << "Invalid input!\n";
    }
  } while (!return_val);

  return 0;
}

原代码问题分析

  • 两个输入循环逻辑几乎完全重复,仅提示文本、输入变量、验证逻辑不同,代码冗余严重。
  • validate_input函数同时绑定两个枚举的验证逻辑,耦合度高,无法单独复用某一个枚举的验证规则。
  • 第二个输入的提示文本与枚举实际值不匹配(提示1、2,但枚举值是5、17),会误导用户。

优化方案

核心思路是提取通用输入逻辑,将变化的部分(提示文本、验证规则、目标枚举类型)作为参数传入,彻底消除重复代码。

优化后的代码

#include <iostream>
#include <limits>
#include <functional>

// 定义枚举类型
enum Input1 {Type1 = 1, Type2 = 2, Type3 = 3, Type4 = 4};
enum Input2 {Type11 = 5, Type22 = 17};

// 为每个枚举单独实现验证函数,降低耦合
bool validate_input1(Input1 input) {
    return input == Type1 || input == Type2 || input == Type3 || input == Type4;
}

bool validate_input2(Input2 input) {
    return input == Type11 || input == Type22;
}

// 通用输入获取模板函数:封装所有重复的输入循环逻辑
template<typename EnumType>
EnumType get_valid_input(const std::string& prompt, const std::function<bool(EnumType)>& validator) {
    int raw_input;
    bool is_valid;
    EnumType enum_input;

    do {
        std::cout << prompt;
        std::cin >> raw_input;

        // 统一处理输入失败(如输入非数字)
        if (std::cin.fail()) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            is_valid = false;
            std::cout << "Invalid input!\n";
            continue;
        }

        enum_input = static_cast<EnumType>(raw_input);
        is_valid = validator(enum_input);

        if (!is_valid) {
            std::cout << "Invalid input!\n";
        }
    } while (!is_valid);

    return enum_input;
}

int main() {
    // 调用通用函数获取合法输入,无需重复编写循环
    Input1 eInput1 = get_valid_input<Input1>(
        "Select option: 1. 2. 3. 4.\n",
        validate_input1
    );

    Input2 eInput2 = get_valid_input<Input2>(
        "Select option: 5. 17.\n",
        validate_input2
    );

    // 新增其他枚举输入时,只需添加对应验证函数并调用get_valid_input即可
    return 0;
}

优化点说明

  1. 拆分验证逻辑:将原来的混合验证拆分为单个枚举的专属验证函数,每个函数只负责对应枚举的合法性检查,耦合度大幅降低。
  2. 通用输入函数:通过模板函数封装了输入循环的所有通用逻辑(提示输出、输入读取、错误处理、合法性验证、循环重试),变化部分通过参数传递,彻底消除重复代码。
  3. 修复提示错误:修正了原代码中第二个输入的提示文本,使其与枚举实际值匹配,避免误导用户。
  4. 扩展性强:后续新增枚举类型时,只需添加对应的验证函数,直接调用get_valid_input即可,无需重复编写循环代码。

进一步优化方向

如果需要更灵活的验证规则,可以将验证器改为接受合法值集合,例如:

template<typename EnumType>
EnumType get_valid_input(const std::string& prompt, const std::initializer_list<EnumType>& valid_values) {
    int raw_input;
    bool is_valid;
    EnumType enum_input;

    do {
        std::cout << prompt;
        std::cin >> raw_input;

        if (std::cin.fail()) {
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            is_valid = false;
            std::cout << "Invalid input!\n";
            continue;
        }

        enum_input = static_cast<EnumType>(raw_input);
        // 检查输入是否在合法值集合中
        is_valid = std::find(valid_values.begin(), valid_values.end(), enum_input) != valid_values.end();

        if (!is_valid) {
            std::cout << "Invalid input!\n";
        }
    } while (!is_valid);

    return enum_input;
}

// 调用方式
Input1 eInput1 = get_valid_input<Input1>(
    "Select option: 1. 2. 3. 4.\n",
    {Type1, Type2, Type3, Type4}
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:47:35