地址数组,返回值为enum

时间:2017-03-02 11:58:13

标签: c++ arrays enums

这是我的问题: 我定义了一些值:

enum HarmCons
{
  val1 = 0,
  val2 = 2,
  val3 = 4,
  val4 = 6
};

我有一个数组

int foo [7] = { 16, 2, 77, 40, 1222, 34, 5};  

我从输入文件读入。我也有这个:

char types[15] = "val1,val3,val4";

现在我想用逗号分隔字符串并在地址(循环中)foo中的条目。所以字符串的第一部分是val1,它应该返回16。 我试过foo[val1] 哪个工作正常。问题是通过分离字符串,我将总是得到一个字符串或东西,我不能通过字符串来处理数组。 是否有可能以一种我可以使用结果来处理数组的方式来分隔字符串?

3 个答案:

答案 0 :(得分:1)

这是接近它的一种方法。

一些注意事项:

  1. 转换器功能是根据专业仿函数实现的。

  2. 用小函数表示的逻辑。

  3. 评论内联

  4. -

    #include <type_traits>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <sstream>
    #include <vector>
    #include <iostream>
    #include <iomanip>
    
    // general concept of value conversion
    template<class From, class To>
    struct converter;
    
    // helper function to select correct converter class
    template<class To, class From>
    To convert(From&& from)
    {
        return converter<std::decay_t<From>, To>()(std::forward<From>(from));
    };
    
    enum HarmCons
    {
        val1 = 0,
        val2 = 2,
        val3 = 4,
        val4 = 6
    };
    
    // specialise for converting from string to our enum
    template<>
    struct converter<std::string, HarmCons>
    {
        HarmCons operator()(std::string in) const {
            using namespace std::literals;
            std::transform(std::begin(in), std::end(in), std::begin(in), [](auto&& c) { return std::tolower(c); });
            if (in == "val1") return HarmCons ::val1;
            if (in == "val2") return HarmCons ::val2;
            if (in == "val3") return HarmCons ::val3;
            if (in == "val4") return HarmCons ::val4;
            throw std::invalid_argument("out of range: "s + in);
        }
    };
    
    // helper functions
    template<class Sequence, class F>
    void for_each_comma(Sequence&& seq, F&& f)
    {
        std::istringstream splitter(std::forward<Sequence>(seq));
        std::string name;
        while(std::getline(splitter, name, ','))
        {
            f(name);
        }
    };
    
    std::vector<int> read_int_array(std::istream& is)
    {
        std::vector<int> values;
        int N;
        is >> N;
        values.resize(N);
        for (int i = 0 ; i < N ; ++i) {
            is >> values[i];
        }
        return values;
    }
    
    std::string dequoted_string(std::istream& is)
    {
        std::string result;
        is >> std::quoted(result);
        return result;
    }
    
    // test against any istream
    void test(std::istream& input)
    {
        // read in test data
        input.exceptions(std::ios_base::badbit);
        auto values = read_int_array(input);
    
        // read in comma- delimted string
        auto value_names = dequoted_string(input);
    
        // perform conversion and lookup
        for_each_comma(value_names, [&](auto&& name){
            auto cons = convert<HarmCons>(name);
            std::cout << values.at(cons) << '\n';
        });
    }
    
    // our test
    int main()
    {
    
        std::istringstream testinput(R"__(
    7
    16 2 77 40 1222 34 5
    "val1,val3,val4"
    )__");
    
        test(testinput);
    }
    

    预期产出:

    16
    1222
    5
    

答案 1 :(得分:1)

您似乎正在尝试使用锤子来驱动螺丝。数组是一个很好的数据结构,但并不适合所有问题。

  

将始终获取字符串或其他内容,我无法通过字符串

来寻址数组

确实,你做不到。所以你需要的不是数组。看起来你有一个从字符串到整数值的映射。这种映射的数据结构是......地图(也称为关联数组,字典,......)

标准库有一个实现:std::map<std::string, int>。根据您的使用情况,您可能希望使用地图替换枚举或数组。

答案 2 :(得分:-1)

如果你真的希望拆分字符串,你可以这样做,只需将最后的字符与描述为字符的数字进行比较 有点像这样:

Scripting

使用循环来执行相同类型的操作,但是随着数字的增加,数量增加0,数百,等等,随着时间的推移添加。
然后你可以使用那个int var来访问数组 然而,切换案例可能是比if语句更好的实现方式。