Frage zu Strukturen und Funktionen
-
steht eigentlich in dem Post...
Beispiel:1.Ich starte das Programm und werde aufgefordert ein Element einzugeben,über das ich mehr wissen will.
2.Ich gebe "Wasserstoff" ein.
Im Programm sind alle Elemente als Strukturen gespeichert.
3.Die Funktion "ausgeben" führt ihre Anweisungen mit dem angegebenen Parameter.Also "Wasserstoff" aus.
4.Auf dem Bildschirm erscheinen die chemischen Daten von dem Element Wasserstoff.Die Frage war :wie schaffe ich es,dass meine Funktion seine Anweisungen nicht mit dem Parameter "auswahl" ausführt,denn so heißt die eingegebene Variable,sondern ,wie oben beschrieben,mit dem Parameter "Wasserstoff",also dem Wert der Variablen.
Hoffe das ist verständlich...
-
Achso, Du suchst nach einer einfachen Parameterübergabe.
void ausgeben(const std::string& auswahl) { std::cout << /* ... */; } int main() { std::string eingabe; std::cin >> eingabe; ausgeben(eingabe); }Natürlich hat ausgeben jetzt erstmal nur den String. Aber die Frage, wie Du über string zu einer Struktur-Instanz kommst, kann man natürlich nur beantworten, wenn man weiß, wie diese gespeichert sind.
Hilft Dir das?
-
Ganz einfach: du brauchst eine Funktion, die dem Namen "Wasserstoff" die Elemetinstanz zuordnet. Also sowas wie
element get_element(string name) { // suche nach name in allen Elementen } ... ausgeben(get_element(auswahl));Möglich wäre auch eine einfach Map, bei der Funktion bist du aber flexibler bei verschiedenen Schreibweisen (wenn der Nutzer z.B. auch "H" eingeben darf).
-
Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map
std::map< chemicalElements, const std::string > elementsNun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels
cout << wasserstoffaus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.
Kannst es ja mal so versuchen, wenn du nicht weiter kommst melde dich einfach, dann wird dir sicherlich geholfen;-)( hatte aber jetzt echt keine Lust kurz den Code zu schreiben
)Lg freeG
-
fr33g schrieb:
Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map
std::map< chemicalElements, const std::string > elementsNun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels
cout << wasserstoffaus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.
Kannst es ja mal so versuchen, wenn du nicht weiter kommst melde dich einfach, dann wird dir sicherlich geholfen;-)( hatte aber jetzt echt keine Lust kurz den Code zu schreiben
)Lg freeG
So werde ich es mal versuchen.Habe zwar noch nie etwas von Maps gehört aber ich schau mal ob ich das hinkrieg.
Danke für die schnellen Antworten,ich melde mich wieder,wenn ich es ausprobiert habe.
-
fr33g schrieb:
std::map< chemicalElements, const std::string > elementsDu meinst
std::map<std::string, ChemicalElement> Elements;oder?
-
DocShoe schrieb:
fr33g schrieb:
std::map< chemicalElements, const std::string > elementsDu meinst
std::map<std::string, ChemicalElement> Elements;oder?
Ja klar
, sorry war mein Fehler, passiert mal eben so auf die schnelle 
Danke für den Hinweis
Lg freeG
-
Das "Ultra-Design" wäre natürlich ein Singleton mit mehreren Instanzen der Klasse (also allen verfügbaren Elementen), einer Zugriffsfunktion per String, die die deutsche Bezeichnung, die internationale Bezeichnung und das Elementsymbol durchsucht und, wenn verfügbar, die passende Instanz (sonst vielleicht eine Null-Instanz) zurückgibt, die man dann per Memberfunktion ausgeben kann oder ihre Informationen in einem String zusammengefasst bekommen kann, der dann ausgegeben werden kann.

-
Ultra-Design und Singleton wirken geradezu parodisch, wenn man die parallele "Diskussion" in meinem Thread betrachtet (auch sonst).

-
Kann mir mal jemand zeigen wie genau das mit der Map und dem Überladen in der Klasse funktionieren würde?Krieg das noch nicht so ganz hin.
-
fr33g schrieb:
Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map
std::map< chemicalElements, const std::string > elementsNun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels
cout << wasserstoffaus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.
Ich würde das eher andersherum verwenden - der erste Template-Parameter von map<> ist der Suchschlüssel

@Babb: Wie weit bist du denn schon gekommen? Die Operator-Überladung brauchst du nicht unbedingt für den Anfang, da reicht es auch, eine Ausgabe-Methode für deine Klasse zu definieren.
Zu der map:
map<string,Element> Periodensystem; //Periodensystem füllen: Periodensystem["Wasserstoff"] = Element(1,"H",...); Periodensystem["Helium"] = Element(2,"He",...); ... //Suchen und ausgeben cin>>name; map<string,Element>::iterator pos = Periodensystem.find(name); if(pos != Periodensystem.end()) pos->print(); else cout<<name<<" wurde noch nicht entdeckt"<<endl;
-
map<string,Element> Periodensystem; //Periodensystem füllen: Periodensystem["Wasserstoff"] = Element(1,"H",...); Periodensystem["Helium"] = Element(2,"He",...); ... //Suchen und ausgeben cin>>name; map<string,Element>::iterator pos = Periodensystem.find(name); if(pos != Periodensystem.end()) pos->print(); else cout<<name<<" wurde noch nicht entdeckt"<<endl;Und das soll einfach so in die Klasse? Ich nehm mal an,dass "Element"der Name der Struktur sein soll,in der die Elemente gespeichert sind und "Periodensystem" der Name der Map (oder meiner Klasse?) ist.
Brauch ich (mehr als) den Header <map> ?Bisschen viele Fragen,ich weiß aber ich hab mich mit Maps noch nie auseinander gesetzt und auch mit Klassen habe ich in C++ noch nicht viel gearbeitet,also bin ich mit der Syntax kein bisschen vertraut.
-
Klar kannst du das alles in eine Klasse kapseln, in dem Fall solltest du die map<> selber eventuell umbenennen (und als privaten Member in die PeriodenSystem-Klasse packen). Der Code dort oben sollte nur demonstrieren, wie du die map verwenden kannst.
-
Ich geb dir mal ein Grundgerüst:
ChemicalElement.h:
#ifndef CHEMICAL_ELEMENT_H #define CHEMICAL_ELEMENT_H #include <string> class ChemicalElement { std::string international_name; std::string german_name; std::string element_symbol; int atomic_number; double element_weight; public: ChemicalElement(std::string const &p_international_name, std::string const &p_german_name, std::string const &p_element_symbol, int p_atomic_number, double p_element_weight); ChemicalElement(); ~ChemicalElement(){} std::string GetInformationString(); }; #endif //CHEMICAL_ELEMENT_HChemicalElement.cpp:
#include "ChemicalElement.h" #include <map> #include <iostream> ChemicalElement::ChemicalElement(std::string const &p_international_name, std::string const &p_german_name, std::string const &p_element_symbol, int p_atomic_number, double p_element_weight) : international_name(p_international_name) , german_name(p_german_name) , element_symbol(p_element_symbol) , atomic_number(p_atomic_number) , element_weight(p_element_weight) { } ChemicalElement::ChemicalElement() : international_name("") , german_name("") , element_symbol("") , atomic_number(0) , element_weight(0.0) { } std::string ChemicalElement::GetInformationString() { //Hier die Informationen zusammenstellen und zurückgeben! } std::map<std::string, ChemicalElement> element_map; void init_element_map() { element_map["Wasserstoff"] = ChemicalElement("Wasserstoff", "Hydrogenium", "H", 1, 1.004); //andere Elemente hinzufügen } int main() { init_element_map(); while(true) //hier kann man natürlich noch eine "Nochmal?-Abfrage" einbauen { std::string element_name; //Element abfragen std::map<std::string, ChemicalElement>::iterator iter = element_map.find(element_name); if(iter == element_map.end()) { std::cout << "Element existiert nicht!\n"; } else { std::cout << iter->second.GetInformationString(); } } }(OK, das ist jetzt noch nicht perfekt gekapselt, aber es zeigt dir schonmal die Syntax
)
-
ChemicalElement();Ich mag diese Angewohnheit, Konstruktoren ohne sinnvolle Initialisierung einfach mal grundsätzlich anzubieten, nicht besonders. Hier ist halt etwas schade, dass man ohne Defaultkonstruktor den
std::map::operator[]nicht mehr benutzen kann, dann müsste man eben zuinsert()greifen.~ChemicalElement(){}Wozu?
std::string GetInformationString();Hier fehlt eine
const-Qualifizierung.std::map<std::string, ChemicalElement> element_map;Würde ich eher lokal deklarieren und übergeben. Eventuell wäre
typedefnicht schlecht.
-
@Nexus:
Konstruktor - richtig, den habe ich erst nachher eingefügt, weil mir eingefallen ist, dass es sonst für Einsteiger noch komplizierter wird.
Destruktor - Angewohnheit, den mit dazu zu schreiben
const - richtig, vergessen, wenn auch hier nicht so wichtig
typedef - mag ich in dem Fall nicht so (zumindest bei zweifacher Verwendung), Lokalisierung stimmt, ich habe ja gesagt, ich würde es am liebsten in einer Art Singleton machen, das wäre jetzt für den TE AFAIK aber zu kompliziert.
-
CStoll schrieb:
fr33g schrieb:
Ich würde mir eine Klasse chemicalElements erstellen, diese hat eben die verschiedenen Datenmember wie Ordnungszahl, Hauptgruppe, Periode, Massenzahl, Elektronegativität und so weiter. Dann überladest du für diese Klasse den Ausgabeoperator. Du erstellst dann alle Elemente und wirfst sie zum Beispiel in eine Map
std::map< chemicalElements, const std::string > elementsNun ließt du die Eingabe vom User ein und machst eine Funktion, die deine Map nach dem eingegebenen Element durchsucht. Ist dieses Element gefunden gibst du es mittels
cout << wasserstoffaus( du musst natürlich wie gesagt den Ausgabeoperator überladen haben.
Ich würde das eher andersherum verwenden - der erste Template-Parameter von map<> ist der Suchschlüssel

fr33g schrieb:
DocShoe schrieb:
fr33g schrieb:
std::map< chemicalElements, const std::string > elementsDu meinst
std::map<std::string, ChemicalElement> Elements;oder?
Ja klar
, sorry war mein Fehler, passiert mal eben so auf die schnelle 
Danke für den Hinweis
Lg freeG

Lg freeG
-
Vielen Dank,wxSkip!
Hat sehr geholfen die Syntax zu verstehen.Ich setz den Entwurf dann wohl morgen um.
Vielen Dank an die vielen hilfreichen und extrem schnellen Antworten,nettes Forum