2017-03-02 98 views
0

的返回值這是我的問題: 從來就定義了一些值:地址陣列枚舉

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] 它工作正常。問題是,通過分隔字符串,我總是會得到一個字符串或某些東西,我無法用字符串來尋址數組。 有沒有可能以一種我可以使用結果來解決數組的方式來分隔字符串?

+0

這些名稱是否總是按照'val1,val2,val3'的順序排列,或者它們可能存在空位或未被排序或不遵循這種固定模式? –

+0

在C++中沒有反射字符串來枚舉,你可以看看庫[更好的枚舉](https://github.com/aantron/better-enums)來幫助那部分。 – Jarod42

+0

有13個可能的名稱,它不是固定數量的名稱,它們也沒有訂購。 – WinterMensch

回答

1

看來你試圖用錘子將螺絲。數組是一個很好的數據結構,但不適合所有問題。

總是會得到一個字符串或東西,我不能被串

實際上解決一個數組,你不能。所以你需要一個非數組的東西。看起來你有一個從字符串到整數值的映射。這種映射的數據結構是...映射(也稱爲關聯數組,字典......)

標準庫爲您提供了一個實現:std::map<std::string, int>。根據您的使用情況,您可能需要將枚舉或陣列替換爲地圖。

+0

事實上,擺脫枚舉和使用地圖直接解決這個沒有任何麻煩。 +1 –

1

下面介紹一種方法。

一些注意事項:在專門的函子方面實現

  1. 轉換功能。

  2. 以小函數表示的邏輯。

  3. 評論直列

-

#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

如果你真的希望分割字符串,你可以這樣做,並簡單地比較最後的字符和數字描述爲字符。
排序是這樣的:

If (char1 == '1') 
    Then set a int var to 1 

並與一個循環做同樣的事情,但隨着0號爲數十,數百,等等加入,當您去。
然後,您可以使用該int var訪問數組。
然而,switch語句可能會比if語句更好地實現它。