如何让char []与std :: map一起使用

时间:2011-06-02 03:54:52

标签: c++ arrays stl map

回答后编辑:

应为<提供

std::map。有关最佳做法的更多信息,请参阅James McNellis的回答

此问题中包含的代码编写得很糟糕。这只是因为我正在玩SPOJ并且输入数据严格有效。 std::string方法是我最初选择的方法,但结果不够快。

谢谢。


我知道我无法直接使用char[]地图,例如map<char[], int>。因此我把它放在课堂上。但它仍然可以通过编译。如何处理?


#include <stdio.h>
#include <map>

using namespace std;

class id {
public:
    char v [30];
};

int main () {
    map<id, int> m;
    id a;
    while (gets(a.v)) {
        m[a]++;
    }
    return 0;
}

/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = id]’:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_map.h:418:   instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = id, _Tp = int, _Compare = std::less<id>, _Alloc = std::allocator<std::pair<const id, int> >]’
prog.cpp:15:   instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’

它似乎与比较有关,但我仍处于黑暗中。

3 个答案:

答案 0 :(得分:6)

首先要做的事情是:永远不要使用gets。它无法安全使用,任何使用它的程序都存在安全漏洞。没有办法限制gets可以写入您提供的缓冲区的字符数,因此无法防止缓冲区溢出。如果确实需要使用C I / O库,则应使用fgets代替,这样可以指定要读取的最大字符数。

您看到此错误的原因是您使用的密钥类型必须以某种方式进行比较。默认情况下,std::map使用operator<,您没有为id定义,因此编译错误。您需要定义operator<来比较两个id对象,或者您需要编写一个可用于比较两个对象的比较器仿函数。无论您选择哪种,比较器都必须提供strict-weak ordering

由于您使用C ++编程,因此理想的解决方案是使用惯用的C ++:

std::map<std::string, int> m;
std::string s;
while (std::cin >> s) {
    m[s]++;
}

std::string已提供operator<提供词典排序,因此您无需自行定义比较器。

答案 1 :(得分:3)

您需要实施<运算符

class id {
public:
    char v [30];
    bool operator<(const id &rhs) const{
        return strcmp(v,rhs.v) < 0;
    }
};

编辑:作为旁注,你的代码是一种非常糟糕的做事方式。请参阅一些答案以解释原因。

答案 2 :(得分:0)

为了插入地图,地图需要能够比较id。您尚未提供运营商的实施&lt;它可以使用。您有两种选择:

  1. 提供一个例子给出另一个答案。
  2. 改用std :: string。
  3. 我认为你应该使用std :: string。您可以在需要时使用.c_str()方法将其转换为char数组。