繁体   English   中英

使用C ++ STL将C样式的字符串映射到int?

[英]Map C-style string to int using C++ STL?

stringint映射工作正常。

std::map<std::string, int> // working

但是我想将C-style字符串映射到int

例如:

char A[10] = "apple";
map<char*,int> mapp;
mapp[A] = 10;

但是,当我尝试访问映射到“苹果”的值时,我得到的是垃圾值而不是10。为什么它的行为与std::string

 map<char*,int> mapp; 

它们的键类型不是“ c string” 至少不是这样,如果我们将c字符串定义为“带有空终止符的字符数组”。 键类型为char* ,它是指向字符对象的指针。 区别很重要。 您没有在地图中存储字符串。 您正在存储指针,并且字符串位于其他位置。

除非您使用自定义比较功能对象,否则默认情况下std::map使用operator<(const key_type&,key_type&) 当且仅当两个指针指向同一个对象时,它们才相等。

这是三个对象的示例:

char A[] = "apple";
char B[] = "apple";
const char (&C)[6] = "apple"

前两个是数组,第三个是左值引用,该引用绑定到也是数组的字符串文字对象。 作为单独的对象,它们的地址当然也不同。 因此,如果您要编写:

mapp[A] = 10;
std::cout << mapp[B];
std::cout << mapp[C];

每个输出将为0,因为您尚未初始化mapp[B]mapp[C] ,因此它们将由operator[]进行值初始化。 即使每个数组包含相同的字符,键值也不同。

解决方案:不要使用operator<来比较指向c字符串的指针。 使用std::strcmp代替。 对于std::map ,这意味着使用自定义比较对象。 但是,您尚未完成警告。 您仍然必须确保字符串必须保留在内存中,只要它们由映射中的键指向即可。 例如,这将是一个错误:

char A[] = "apple";
mapp[A] = 10;
return mapp; // oops, we returned mapp outside of the scope
             // but it contains a pointer to the string that
             // is no longer valid outside of this scope

解决方案:请注意范围,或仅使用std::string

可以做到,但是您需要更智能的string版本:

struct CString {
    CString(const char *str) {
        strcpy(string, str);
    }
    CString(const CString &copy); // Copy constructor will be needed.
    char string[50]; // Or char * if you want to go that way, but you will need
                     // to be careful about memory so you can already see hardships ahead.
    bool operator<(const CString &rhs) {
        return strcmp(string, rhs.string) < 0;
    }
}

map<CString,int> mapp;
mapp["someString"] = 5;

但是,您可能会看到,这是一个巨大的麻烦。 可能有些事情我也错过或忽略了。

您还可以使用比较功能:

struct cmpStr{
    bool operator()(const char *a, const char *b) const {
        return strcmp(a, b) < 0;
    }
};

map<char *,int> mapp;
char A[5] = "A";
mapp[A] = 5;

但是有很多外部内存管理,如果A s内存消失但映射仍然存在,UB会发生什么。 这仍然是一场噩梦。

只需使用std::string

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM