地址阵列枚举
的返回值这是我的问题: 从来就定义了一些值:地址阵列枚举
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";
现在我想单独由commata和地址字符串(在一个循环中)的条目foo
。所以字符串的第一部分应该是val1
,它应该返回16
。 我试过foo[val1]
它工作正常。问题是,通过分隔字符串,我总是会得到一个字符串或某些东西,我无法用字符串来寻址数组。 有没有可能以一种我可以使用结果来解决数组的方式来分隔字符串?
看来你试图用锤子将螺丝。数组是一个很好的数据结构,但不适合所有问题。
总是会得到一个字符串或东西,我不能被串
实际上解决一个数组,你不能。所以你需要一个非数组的东西。看起来你有一个从字符串到整数值的映射。这种映射的数据结构是...映射(也称为关联数组,字典......)
标准库为您提供了一个实现:std::map<std::string, int>
。根据您的使用情况,您可能需要将枚举或阵列替换为地图。
事实上,摆脱枚举和使用地图直接解决这个没有任何麻烦。 +1 –
下面介绍一种方法。
一些注意事项:在专门的函子方面实现
转换功能。
以小函数表示的逻辑。
评论直列
-
#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
如果你真的希望分割字符串,你可以这样做,并简单地比较最后的字符和数字描述为字符。
排序是这样的:
If (char1 == '1')
Then set a int var to 1
并与一个循环做同样的事情,但随着0号为数十,数百,等等加入,当您去。
然后,您可以使用该int var访问数组。
然而,switch语句可能会比if语句更好地实现它。
这些名称是否总是按照'val1,val2,val3'的顺序排列,或者它们可能存在空位或未被排序或不遵循这种固定模式? –
在C++中没有反射字符串来枚举,你可以看看库[更好的枚举](https://github.com/aantron/better-enums)来帮助那部分。 – Jarod42
有13个可能的名称,它不是固定数量的名称,它们也没有订购。 – WinterMensch