我在最后一天一直在解决这个问题,我仍然对以下代码的解决方案感到失望:
#include <stdio.h>
#include <iostream>
#include <map>
int main()
{
std::map<char *, char *> ourmap;
std::map<char *, char *>::iterator ourmap_it;
ourmap["hello"] = "world";
ourmap["hello"] = "earth";
char * key = new char[5];
key[0] = 'h';
key[1] = 'e';
key[2] = 'l';
key[3] = 'l';
key[4] = 'o';
char * key_other = new char[5];
key_other[0] = 'h';
key_other[1] = 'e';
key_other[2] = 'l';
key_other[3] = 'l';
key_other[4] = 'o';
ourmap[key] = "venus";
ourmap[key] = "mars";
ourmap[key_other] = "jupiter";
for (ourmap_it = ourmap.begin(); ourmap_it != ourmap.end(); ++ourmap_it)
{
printf("map[%s] %s\n", ourmap_it->first, ourmap_it->second);
}
ourmap.clear();
delete key;
delete key_other;
return 0;
}
如果您在动态键上执行find
,则不会覆盖密钥,行为也相同。输出详细解释了
map[hello] earth
map[hello] mars
map[hello] jupiter
为什么map
不find
两个值相等,如果const char *
为@key
,@key
为@key_other
我要使用不同的容器吗?或者使用不同的代码(以不同的方式定义变量)。
在上面的代码中使用动态键并没有看到,但是我的实际代码需要动态密钥,如果从文件中读取键值作为代码中的定义,并且因为我不知道密钥的大小在给定的文件中,它必须是动态的。问题是虽然我可以设置密钥但我无法检索到值。
我正在考虑创建一个我自己的发现,它会在键上找到strcmp
以找出等价,但这似乎很简单,所以在我提出之前先咨询SO
。
任何帮助都会很棒。感谢
答案 0 :(得分:8)
好。一些想法。
"hello"
,但是没有足够的空间来终止它。当您尝试打印时会发生未定义的行为。"hello"
的2个实例具有相同的指针。该标准将该选项留给了实现。std::string
代替char *
来解决您的大部分问题。让我们修复代码中的一些错误,并继续讨论它:
int main() {
std::map<char const *, char const *> ourmap;
std::map<char const *, char const *>::iterator ourmap_it;
ourmap["hello"] = "world"; // (1)
ourmap["hello"] = "earth"; // (2)
char * key = new char[6];
key[0] = 'h';
key[1] = 'e';
key[2] = 'l';
key[3] = 'l';
key[4] = 'o';
key[5] = '\0';
char * key_other = new char[6];
key_other[0] = 'h';
key_other[1] = 'e';
key_other[2] = 'l';
key_other[3] = 'l';
key_other[4] = 'o';
key_other[5] = '\0';
ourmap[key] = "venus"; // (3)
ourmap[key] = "mars"; // (4)
ourmap[key_other] = "jupiter"; // (5)
for (ourmap_it = ourmap.begin(); ourmap_it != ourmap.end(); ++ourmap_it)
printf("map[%s] %s\n", ourmap_it->first, ourmap_it->second);
}
我在代码中引用了4个位置。我们对这些钥匙了解多少。
嗯,我们知道(2) != (3) != (5)
。但是我们推断出(1) ?= (2)
的诅咒。那么,通常,(1)和(2)会有所不同。但是,标准允许(但不要求)编译器合并这两个字符串文字以节省内存。话虽如此,大多数编译器都会这样做,尤其是在一个编译单元中。
所以,我们假设优化发生了。
所以,让我们运行第1步。我们的地图现在看起来像:
"hello" (1) => "world"
让我们运行第2步。
"hello" (1) => "earth"
请注意,我们在地图中只有一个元素,因为(1) == (2)
。
让我们运行第3步。
"hello" (1) => "earth"
"hello" (3) => "venus"
我们现在在地图中有两个元素,因为我们使用两个不同的指针作为我们的键。
我要停在这里,但我认为这说得很清楚。
或者,我们可以使用std :: string。
int main() {
std::map<std::string, std::string> ourmap;
std::map<std::string, std::string>::iterator ourmap_it;
ourmap["hello"] = "world";
ourmap["hello"] = "earth";
char * key = new char[6];
key[0] = 'h';
key[1] = 'e';
key[2] = 'l';
key[3] = 'l';
key[4] = 'o';
key[5] = '\0';
char * key_other = new char[6];
key_other[0] = 'h';
key_other[1] = 'e';
key_other[2] = 'l';
key_other[3] = 'l';
key_other[4] = 'o';
key_other[5] = '\0';
ourmap[key] = "venus";
ourmap[key] = "mars";
ourmap[key_other] = "jupiter";
for (ourmap_it = ourmap.begin(); ourmap_it != ourmap.end(); ++ourmap_it)
printf("map[%s] %s\n", ourmap_it->first.c_str(), ourmap_it->second.c_str());
}
此处输出为:
map[hello] jupiter
这是因为std :: string以<
的方式实现char *
。它比较字符串的内容。
只是为了扩展最后一件事。以下是正在实施的比较器的示例。
struct comparator {
bool operator()(const char * lhs, const char * rhs) const {
return strcmp(lhs, rhs) < 0;
}
};
int main() {
std::map<char const *, char const *, comparator> ourmap;
std::map<char const *, char const *, comparator>::iterator ourmap_it;
...
在这种情况下,就像std :: string一样,我们会看到以下输出:
map[hello] jupiter