2015-06-12 3 views
1

В настоящее время я пишу программу для командной строки, где я сохранил категории и решения в map<string, vector<string>>. Ключевым значением является категория, а вектор - вектор строк решения.User select item in map

Я хотел бы предложить пользователю выбрать категорию, однако я не уверен, что это лучший способ сделать это, поскольку я не хочу принуждать пользователя вручную вводить категорию, и поэтому я получаю только int с их выбор.

Есть ли способ использовать int для доступа к карте? (Например solutionMap [2] = второе значение?)

Вот отрывок из моего кода только для уточнения

cout << "\nCategories:\n-----------" << endl; 
int categoryCount = 1; 
for (map<string, vector<string> >::iterator it = solutionMap.begin(); it != solutionMap.end(); ++it){ 
    cout << categoryCount << ": " << it->first << endl; 
    ++categoryCount; 
} 

// Prompt user for selection and save as currentCategory 
int currentCategory; 
bool isValid = false; 

do{ 
    cout << "Please enter the number of the category you would like to use: "; 
    cin >> currentCategory; 

    // if cin worked and number is in range, continue out of the loop 
    if (cin.good() && currentCategory <= solutionMap.size()){ 
     isValid = true; 
    } 
    else{ 
     cout << "Invalid entry!" << endl; 

     // Clear the buffer 
     cin.clear(); 
     cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    } 
} while (!isValid); 

То, что я хотел бы сделать в этот момент отправить номер к игре класс и есть выбор случайного решения из вектора с использованием выбранного значения ключа, однако, насколько я знаю, мне нужен выбор в виде строки, чтобы найти его.

Любая помощь будет оценена!

+0

Я должен добавить, что я попытался использовать итератор и увеличил его на значение, указанное-1, но, похоже, не смог заставить это работать. Хотя я, вероятно, неправильно ошибся –

+0

, почему именно вам нужна карта? кажется, что создание вектора структур, у которых есть название категории и решения, может быть лучше. – dwcanillas

+0

Категории и решения поступают из файла ifstream из файла CSV. Программа должна сохранять эти данные, даже если файл csv изменяется. Я решил, что карта будет лучшим способом сохранить эту информацию. По-прежнему учитесь по большей части, поэтому получение этой информации и создание структур немного выше моих способностей/ноу-хау –

ответ

0

Если вы хотите получить доступ к карте, используя целочисленный индекс, вы можете выполнить следующие действия:

auto ix=solutionMap.begin(); // bidirectional iterator to the map 
advance (ix,currentCategory); // move the iterator 
cout << "choice is "<<ix->second<<endl;  // here you are 

Но будьте осторожны: как только вы вставляете/удалить элемент, то Ordre элементов не может больше соответствуют отображаемому меню.

Как это работает?

Итератор к картам двунаправленный: вы можете двигаться вперед или назад только по одному элементу за раз. advance() повторы этой операции правильное число раз

Альтернативы

Если вы на самом деле не использовать карту в качестве ассоциативного массива, и в основном используют меню и индексы, вы должны выбрать другой вариант, используя вектор вместо карты:

vector<pair<string, vector<string>> solutionMap; 

Вы можете легко получить доступ к элементам, используя их индекс. Если вам нужно случайно найти определенный элемент, используя ключевую строку, вы все равно можете использовать find_if().

+0

Большое спасибо. Я действительно пытался сделать именно это, но не знал о функции advance(). Я попытался добавить к нему, как я мог, указав на успех, но теперь у меня это работает. Еще раз спасибо –

+0

@KeeganTales добро пожаловать! Добавление на итераторе возможно только для [итераторов произвольного доступа] (http://www.cplusplus.com/reference/iterator/). Итераторы учитывают ограничения базовой структуры данных. Вот почему итераторы карт являются двунаправленными, тогда как векторными итераторами являются, например, произвольный доступ. – Christophe