我正在尝试将char数组值添加到地图中,但是在显示char数组的值时,不会显示整数值。 即ii.first未显示,但ii.second正确显示。
以下是我正在运行的完整代码,
#include <iostream>
#include <cstring>
#include <map>
#include <utility>
using namespace std;
class map_demo {
public:
class cmp_str {
public:
bool operator() (char const *a, char const *b) {
return std::strcmp(a, b) <0;
}
};
private:
typedef map <char*, int, cmp_str> ptype;
ptype p;
public:
void set_value() {
char name[20];
int empid;
cout<<"Enter the employee name\n";
cin.getline(name,20);
// cout<<"name entered=:"<<name;
cout<<"Enter the employee id\n";
cin>>empid;
this->p.insert(map<char *,int>::value_type(name,empid));
}
void get_value() {
cout << "Map size: " << p.size() << endl;
for(ptype::iterator ii=p.begin(); ii!=p.end(); ++ii) {
cout <<"the first="<< (*ii).first << ": " << (*ii).second << endl;
}
}
};
//=====================================================================
int main() {
map_demo mp1;
mp1.set_value();
mp1.get_value();
}
运行代码时获得的输出:
Enter the employee name
farhan
Enter the employee id
909
Map size: 1
the first=: 909
这里的first = farhan:909
应该是正确的输出,任何人都可以让我明白我在哪里做错了吗?
答案 0 :(得分:2)
其他提到的问题是char *。同样在你的情况下,char *变得悬空而你实际上指向垃圾,其背后的原因是,当名称超出范围时释放内存,并且您仍然指向该内存,实际上您需要复制数据在地图上。
这个有效
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include <utility>
using namespace std;
class map_demo
{
public:
class cmp_str
{
public:
bool operator() (char const *a, char const *b)
{
return std::strcmp(a, b) <0;
}
};
private:
typedef map <string, int> ptype;
ptype p;
public:
void set_value()
{
char name[20];
std::string inval;
int empid;
cout << "Enter the employee name\n";
cin.getline(name, 20);
inval = name;
//cout<<"name entered=:"<<name;
cout << "Enter the employee id\n";
cin >> empid;
//this->p.insert(map<char *, int>::value_type(name, empid));
this->p.insert(std::pair<string , int>(inval,empid));
}
void get_value()
{
cout << "Map size: " << p.size() << endl;
for (auto ii = p.begin(); ii != p.end(); ++ii)
{
std::string mysf(ii->first);
//std::cout << mysf << std::endl;
cout << "the first=" << mysf << ": " << (*ii).second << endl;
}
}
};
int main()
{
map_demo mp1;
mp1.set_value();
mp1.get_value();
}
只是一个快速修复,可能需要更多努力才能做得更好。但只是为了给你一个想法。
如果你需要使用char *,那么你可能需要自己批量分配内存,每次你去询问你在数据结构中复制它的名称并检索指向它的指针。要正确处理你使数据结构的方式在结果的清洁方面发生了很大变化,但核心要点是,你需要管理你的内存,复制到一个会持久存在但不会丢失的地方,然后存储一个指向该内存的指针,而不是指当你离开set_value()时释放的内存区域。
答案 1 :(得分:1)
这一行
this->p.insert(map<char *,int>::value_type(name,empid));
向地图添加char*
指针,而不是字符串本身。如果指针
指向堆栈(name []在堆栈上)然后它将是潜在的
每次迭代都使用相同的地址。
使用std :: string
e.g。
typedef std::map<std::string, int> ptype;
...
p.insert(std::make_pair(name,empid))
或手动分配动态内存并跟踪字符串
char* nameStorage = new char[strlen(name)+1];
strcpy(nameStorage,name);
p.insert(std::make_pair(nameStorage,empid));
答案 2 :(得分:1)
您定义了地图的键,如char *
typedef map <char*, int, cmp_str> ptype;
^^^^^
所以在成员函数set_value
void set_value() {
char name[20];
int empid;
//...
this->p.insert(map<char *,int>::value_type(name,empid));
}
为密钥分配了本地可变的name
的地址(更准确地说是数组name
的第一个字符的地址),它将在退出函数后被销毁。
之后,密钥将被取消,因为它将指向一个不存在的字符数组。
此外,密钥应该是可复制的,但是数组没有复制赋值操作符。
您可以使用标准类std::array<char, 20>
作为键类型。例如
typedef map <std::array<char, 20>, int, cmp_str> ptype;
在这种情况下,您还必须更改它将接受此类对象的cmp_str
。
另一种方法是使用标准类std::string
而不是数组。 Foir示例
typedef map <std::string, int> ptype;