Я работаю над программой C++ с периодической таблицей. У меня есть класс Table
с вектором, содержащим указатели на все объекты элемента и unordered_map, который преобразует имена и символы элементов в атомные числа. Он перегружает оператор [], так что Table[const char*]
возвращает указатель на элемент с указанным именем или символом. Это отлично работает, если я жестко ./program H
имя или символ в вызове, как Table["H"]
, но если я вызову программу, например ./program H
и попробуйте Table argv[1]
появляется ошибка out_of_range, даже если H находится в таблице и Table["H"]
работает нормально. Почему он не находит элементы по символу, когда символ является аргументом командной строки, но это происходит, когда символ жестко закодирован?
Вот мой код, содержащий только один элемент, чтобы он был максимально простым:
#include <stdio.h>
#include <vector>
#include <unordered_map>
#include <cstring>
#include <stdlib.h>
using namespace std;
class Element{
public:
const char* name;//name
const char* sym;//symbol
const int z;//atomic number
const double m;//atomic mass
const double p;//density
const double mP;//melting point
const double bP;//boiling point
const double c;//specific heat
const double eneg;//electonegativity
const int gp;//group
const int pd;//period
Element(const char* n,const char* s,const int an,const double am,
const double d,const double mp,const double b,
const double sh,const double e,const int g,const int pd):
name(n),sym(s),z(an),m(am),p(d),mP(mp),bP(b),c(sh),eneg(e),gp(g),pd(pd)
{}
Element(const Element& e):
name(e.name),sym(e.sym),z(e.z),m(e.m),p(e.p),mP(e.mP),bP(e.bP),c(e.c),
eneg(e.eneg),gp(e.gp),pd(e.pd)
{}
const Element& operator=(const Element& e){
return e;
}
};
Element ah("Surprise","Ah",0,0.0625,0.000001,4999 ,9998,999999,0,0,0);
Element* undiscovered=&ah;
class Table{
public:
vector<const Element*> E_n;//vector<Element> E_n;
unordered_map<const char*,int>E_ns;
const Element* operator[](int i){
return E_n[i];
}
const Element* operator[](const char* n){
try{
return E_n[E_ns.at(n)];
}catch(out_of_range e){
return undiscovered;
}
}
int size(){
return E_n.size();
}
void add(const Element& e){
while(E_n.size()<=e.z)E_n.push_back(undiscovered);
E_n[e.z]=&e;
E_ns[e.name]=e.z;
E_ns[e.sym]=e.z;
}
void print(){
puts("\n");
for(auto e:E_n){
printf("%3d %13s(%3s). m:%7.3f, p:%10f, mp:%7.2f, bp:%7.2f\n",e->z,e->name,e->sym,e->m,e->p,e->mP,e->bP);
}
}
};
Table Elements;
int main(int argc,char **argv){
int i;
Elements.add(Element("Hydrogen","H",1,1.008,0.00009,14.1,20.28,14.304,2.20,1,1));
i=Elements[argv[1]]->z;
if(!i)i=atoi(argv[1]);
if(!i){
printf("There is no element \"%s\".\n",argv[1]);
return 0;
}
printf("%f\n",Elements[i]->m);
return 0;
}
Два const char *
не равны, поскольку один указывает на константу, а другой - нет. Поскольку вы указали карту с помощью указателя, указатели должны были бы быть равны для успеха find
. Вместо этого индексируйте карту, используя std::string
чтобы равные строки определяли местоположение элемента.