[英]C++ STL map not recognizing key
I have this code, CBString is just a string class I use for some processing 我有这个代码,CBString只是我用于某些处理的字符串类
char * scrummyconfigure::dosub(strtype input)
{
CBString tstring;
tstring = input;
uint begin;
uint end;
begin = tstring.findchr('$');
end = tstring.findchr('}',begin);
CBString k = tstring.midstr(begin+2,end-2); // this is BASE
strtype vname = (strtype) ((const unsigned char*)k);
strtype bvar = (strtype) "BASE";
assert(strcmp(bvar,vname) == 0); // this never fails
// theconf is just a struct with the map subvars
// subvars is a map<const char *, const char *>
out(theconf->subvars[bvar]); // always comes up with the value
out(theconf->subvars[vname]); // always empty
uint size = end - begin;
tstring.remove(begin, size);
return (const char *)tstring; // it's OKAY! it's got an overload that does things correctly
//inline operator const char* () const { return (const char *)data; } <-- this is how it is declared in the header of the library
}
Why is it that the strcmp always says the strings are the same, but only the variable I declared as bvar returns anything? 为什么strcmp总是说字符串是相同的,但只有我声明为bvar的变量才会返回任何内容?
//subvars is a
map<const char *, const char *>
// subvars是一个
map<const char *, const char *>
The key of this map isn't a string per-say, but a memory address. 这个映射的关键不是字符串per-say,而是内存地址。 The corresponding check would be
相应的检查将是
assert( bvar == vname);
which will probably fail. 这可能会失败。 You'll need to change the key type to a string class (either
std::string
or CBString
to meaningfully use the map. 您需要将密钥类型更改为字符串类(
std::string
或CBString
以有意义地使用映射。
I'm assuming strtype
is defined in the following way: 我假设
strtype
按以下方式定义:
typedef char * strtype
Your issue is that you're assuming that vname and bvar have the same value, where in reality, they have different values that each point to a block of memory that contains identical data. 您的问题是您假设vname和bvar具有相同的值,实际上,它们具有不同的值,每个值都指向包含相同数据的内存块。
std::map
is dumbly comparing them with ==, and I bet you'd find that if you compared them with ==, you would get false, as expected. std::map
愚蠢地将它们与==进行比较,我打赌你会发现,如果你将它们与==进行比较,你会得到假的,如预期的那样。 Why exactly arent you using the std::string
class? 你为什么不使用
std::string
类?
Edit: I rewrote your method to be less scary: 编辑:我重写了你的方法不那么可怕:
// implied using namespace std;
string ScrummyConfigure::removeVariableOrSomething(string tstring)
{
uint begin; // I'll assume uint is a typedef to unsigned int
uint end;
begin = tstring.find('$', 0);
end = tstring.find('}', begin);
string vname = tstring.substr(begin + 2, end - 2); // this is supposedly BASE
assert(vname == "BASE"); // this should be true if vname actually is BASE
out(this->conf->subvars[bvar]); // wherever theconf used to be, its now a member
out(this->conf->subvars[vname]); // of ScrummyConfigure and its been renamed to conf
uint size = end - begin;
tstring.erase(begin, size);
return tstring; // no casting necessary
}
Just because the strings are the same doesn't mean that std::map will treat them as the same key. 仅仅因为字符串相同并不意味着std :: map会将它们视为相同的键。 That depends on the Compare class that is used by the std::map, which defaults to
less<KeyType>
- which yields the same result as applying the less-than operator. 这取决于std :: map使用的Compare类,默认为
less<KeyType>
- 这会产生与应用less-than运算符相同的结果。
You can define a class that defines operator()
to do a proper comparison on your strtypes and pass that as your third template argument when defining your std::map. 您可以定义一个定义
operator()
的类,以便对strtypes进行正确的比较,并在定义std :: map时将其作为第三个模板参数传递。 Or, as suggested, use std::string as your strtype. 或者,如建议的那样,使用std :: string作为strtype。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.