2

我正在尝试用 2 个字符的单词制作字典,但不太成功这是我的代码:

#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;

int main(int argc, char *argv[]){
    map<char*,int> m;
    //input 5 two-lengthed words 
    for (int i=0;i<5;i++){
        char s[3];
        cin>>s;
        s[2] = '\0';
        m[s]=1; //add a key
    }
    //checking if a word exists.

    cout<<"Word you want to check whether it exists:"<<endl;
    char chck[3];
    cin>>chck;
    chck[2]='\0';
    //I heard this is how you check whether a key exists:
    bool exists = m.find(chck)==m.end(); 
    cout<<((exists)?"Yes!":"No.")<<endl;
    system("pause"); //Yea, system, I know.
    return 0;
}

每当我输入单词,然后当我想检查一个单词是否在字典中时,我总是打印“No.”?
我来自Java,所以我习惯了引用,而不是指针,所以这就是我可能错的地方。我想学习如何正确使用地图,请问我应该在这里做什么?

谢谢

4

3 回答 3

6
//I heard this is how you check whether a key exists:
bool exists = m.find(chck)==m.end(); 

是的,但如果元素存在,则条件为真。你应该调用你的 vaviable notExists

bool notExists = m.find(chck)==m.end();

现在,如果您只想检查作品是否存在,您可以使用std::set<std::string>. 如果你想让这个词成为其他事物的关键,那么你需要std::map<std::string, SomeThingElse>.

忘记那些char*。使用std::strings。

于 2013-03-01T21:39:42.040 回答
2
    m[s]=1; //add a key

每次您“添加一个键”时,您实际上只是获得相同的元素,具有相同的键。键是数组的地址s而不是输入的字符串的值。

尝试打印出容器的大小,您将看到一个元素:

   std::cout << m.size() << '\n';

当您将 achar*放入容器中并使用默认比较函数时,它们仅在它们是相同指针而不是相同字符串时才比较相等:

 char s1[] = "foo";
 char s2[] = "foo";
 assert( s1 == s2 );   // FAILS!

要将字符串值推送到容器中,请使用std::string键,而不是char*

std::string s1 = "foo";
std::string s2 = "foo";
assert( s1 == s2 );   // passes

这避免了比较指针和数组超出范围而在映射中留下悬空指针的整个问题。

于 2013-03-01T21:53:12.220 回答
2

让我们看一下您的代码:

你有一个std::map<char *, int>. 第一个“char *”作为地图的关键是可疑的。将指针存储为键通常不是您真正想要做的。但我们继续阅读。在您的循环内,您有一个要填充的本地数组 s。然后使用该变量索引到地图中。请记住,映射的键是 char*。数组 s 的地址可能在每次循环迭代中都相同。因此,您可能只将一个项目放入您的地图中,并且它仅包含您放入 s 中的最新值。但是等等,情况会变得更糟。一旦你的循环完成, s 就会超出范围,现在取消引用当前存储在映射中的指针是未定义的行为(作为该映射中唯一元素的键。输出 m.size() 到核实)。

将您的地图重新定义std::map<std::string, int>为不存在所有这些问题。

于 2013-03-01T21:53:38.390 回答