Итак, у меня есть два текстовых поля (определены ранее) и два вектора:
std::vector<TCHAR*> v1;
std::vector<int> v2;
и карта:
std::map <TCHAR*, int> m1;
std::map <TCHAR*, int>:: iterator i1;
Карта инициализации:
void mapInit()
{
m1[L"one"] = 1;
m1[L"two"] = 2;
m1[L"three"] = 3;
m1[L"four"] = 4;
m1[L"five"] = 5;
m1[L"six"] = 6;
m1[L"seven"] = 7;
m1[L"eight"] = 8;
m1[L"nine"] = 9;
m1[L"ten"] = 10;
}
Я должен взять слово «один» из первого текстового поля и записать его в вектор «v1» (текстовое поле должно иметь больше слов в будущем, поэтому я не могу сделать это без вектора).
После этого программа должна найти на карте нужное значение по ключу-имени:
TCHAR *zr = v1.at(0); // v1.at(0) has the word `one` atm
i1 = m1.find(zr); // want to get value `1` by key `one`
int z = i1->second; // and get it completely
Я получил ошибку утверждения отладки «map / set iterator not dereferencable» .. 🙁
Если я сделаю все то же самое, но поменяю его на L «one»:
TCHAR *zr = L"one"; //
i1 = m1.find(zr);
int z = i1->second;
так будет работать …
Почему это не работает со значением по вектору? Я проверил с помощью отладчика мое значение вектора — его ‘L «один» тоже! Но все равно не работает …
ПРИМЕЧАНИЕ: я также пытался найти слово без метода .find ():
TCHAR *zr = v1.at(0);
int z = m1[zr]; // - now `z` returns a null...
Если я поменяю ‘v1.at (0)’ на L «one», он снова будет работать
Heeeeeelp 🙁 Почему это не работает?
=================================================
Дааааааа, теперь все работает! 🙂
Легко исправить:
wstring zr = v1.at(0);
int z = m1[zr];
Двойное счастливое лицо)
Спасибо всем за помощь, братан 🙂
Я предполагаю, что «map / set iterator not dereferencable» заключается в том, что вы пытаетесь разыменовать итератор, который указывает на end (), вы должны проверить, действительно ли find что-то нашла.
Причина, вероятно, потому что ваша карта:
std::map <TCHAR*, int> m1;
сохраняет в качестве ключевых указателей, их значения различаются в v1, поэтому он не может найти его. Вы можете проверить это, если хотите сохранить свой дизайн (повторить все значения карты и значения ключа печати, затем сделать то же самое с v1), или сделать это правильно и использовать std :: wstring, как было предложено в комментариях.
Не используйте TCHAR * в качестве ключа карты, это только причинит вам боль и головную боль. Вы будут иметь утечки памяти и / или сбои при обращении к освобожденной памяти.
TCHAR это просто typedef для char, если не unicode, и wchar_t, если unicode.
Вы можете сделать что-то вроде этого
typedef std::basic_string<TCHAR> tstring;
затем объявите вашу карту как
std::map<tstring,int>
Примечание не используйте указатель на строку. Вы должны быть в состоянии преобразовать все, что вы получите от GetWindowText, в строку.
Вы можете использовать Win32 API
tstring window_text(max_window_text,0);
auto ncount = ::GetWindowText(window_hwnd,&window_text[0],window_text.size());
if(ncount){
window_text.resize(ncount);
} else{
// handle failure
}
Это избавит вас от боли.
Знание того, как перейти от TCHAR * к std :: string / wstring, очень важно для возможности написания хороших нативных программ на C ++ для Windows. Это то, что вам нужно изучить, поэтому, если у вас все еще есть проблемы, отправьте код и ошибки. Если вы не научитесь делать это, я бы посоветовал вам не пишите свои программы в Windows на C ++ и вместо этого используйте что-то вроде C #.