C++:如何制作一个简单的字典?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15167291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:06:19  来源:igfitidea点击:

C++: How to make a simple dictionary?

c++dictionary

提问by SmRndGuy

I'm trying to make a dictionary with 2-character words but not so much success Here's my code:

我正在尝试用 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] = '
//I heard this is how you check whether a key exists:
bool exists = m.find(chck)==m.end(); 
'; 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]='
bool notExists = m.find(chck)==m.end();
'; //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; }

Whenever I enter the words, and then when I want to check whether a word is in a dictionary, I always get printed "No."?
I come from Javaso I got used to references, not pointers, so that's where I'm probably wrong. I want to learn how to properly use the maps so can you please what am I supposed to do here?

Thanks

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

谢谢

回答by juanchopanza

    m[s]=1; //add a key

Yes, but the condition is true if the element does notexist. You should call your vaviable notExists:

是的,但如果元素存在,则条件为真。你应该打电话给你的 vaviable notExists

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

Now, if all you want to do is check if a work exists, you can use an std::set<std::string>. If you want the word to be a key to something else, then you need std::map<std::string, SomeThingElse>.

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

Forget about those char*. Use std::strings.

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

回答by Jonathan Wakely

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

Each time you "add a key" you're actually just getting the same element, with the same key. The key is the address of the array s, notthe value of the string entered.

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

Try printing out the size of the container and you'll see a single element:

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

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

When you put a char*in a container and use the default comparison function they only compare equal when they are the same pointer, not the same string:

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

##代码##

To push string values into the container use std::stringkeys, not char*

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

##代码##

This avoids the whole problem of comparing pointers and of the array going out of scope leaving a dangling pointer in the map.

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

回答by Andre Kostur

Let's look at your code a bit:

让我们看一下你的代码:

You have a std::map<char *, int>. That first "char*" is suspicious as a key to the map. Storing pointers as the key isn't often what you really want to do. But we keep reading. Inside your loop you have a local array s that you populate. Then you use that variable to index into the map. Remember that the key to the map is a char*. The address of the array s is likely to be the same on every loop iteration. As a result, you are probably putting only one item into your map, and it only holds the most recent value of what you put into s. But wait, it gets worse. As soon as your loop is done, s goes out of scope and it is now Undefined Behaviour to dereference the pointer that's currently stored in the map (as the key to the one and only element in that map. Output m.size() to verify).

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

Redefine your map to be std::map<std::string, int>to not have all of these problems.

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