Container mit unterschiedlichen Typen als Inhalt



  • Hi,
    ich habe eine Anfängerfrage.
    Eine Liste definiere ich ja z.B so:
    list<string> lstStr;

    Jetzt kann der Inhalt aber immer nur vom Datentyp string sein.
    Ich möchte aber in einer Liste int, string, float und bool Werte Speichern geht das?



  • Schau Dir mal boost.any oder boost.variant an.



  • eine andere Frage ist dann noch, wie du rausfindest was du an welcher Stelle der Liste stehen hast... wenn du wahllos verschiedene Datentypen in die Liste reinstopfst ohne irgendwie die information abzulegen, von welchem Typ die einzelnen Elemente sind, dann weißt du hinterher auch nicht, wie du die Listenelemente weiterverarbeiten kannst.



  • Die Reihenfolge in der ich die Elemente einfüge ist fest und mir bekannt. Das dürfte kein Problem sein. Sind auch nur ca 10 feste Werte.

    Danke für die Antworten! 🙂



  • Mitbewohner schrieb:

    Die Reihenfolge in der ich die Elemente einfüge ist fest und mir bekannt. Das dürfte kein Problem sein. Sind auch nur ca 10 feste Werte.

    Danke für die Antworten! 🙂

    Dann nimm einfach ein struct wo du den ganzen Krempel in die einzelnen Member packst. Container sind für variable Elementzahlen da...



  • Aber ich möchte in einer Schleife die Werte zuweisen.

    Hier mal ein meine Aufgabe:

    Ich habe einen String der sieht so aus:

    20081008100803;baro_rs;1014.4;14.4;0;0;176;S;86;0;no;0.9;185;0.25;7.87;824.48;6;45

    Ich brauche die Werte zwischen den ";" ich hatte mir gedacht mit strtok zu teilen und in einer schleif das ganze den variablen in einer Liste zuzuweisen. Aber durch einen Strukt kann ich nicht durchlaufen, das ist das Problem.



  • Wenn du es pervers magst, kannst du ja auch ein Struct nehmen, das ein Union der entsprechenden Typen beinhaltet plus Identifier. Verschwendet zwar Speicherplatz aber funktioniert. 😉



  • Mitbewohner schrieb:

    Aber ich möchte in einer Schleife die Werte zuweisen.

    Hier mal ein meine Aufgabe:

    Ich habe einen String der sieht so aus:

    20081008100803;baro_rs;1014.4;14.4;0;0;176;S;86;0;no;0.9;185;0.25;7.87;824.48;6;45

    Ich brauche die Werte zwischen den ";" ich hatte mir gedacht mit strtok zu teilen und in einer schleif das ganze den variablen in einer Liste zuzuweisen. Aber durch einen Strukt kann ich nicht durchlaufen, das ist das Problem.

    WTF?
    Und wie willst du das mit einer Liste + Schleife anstellen?



  • Mitbewohner schrieb:

    ...
    Hier mal ein meine Aufgabe:

    Ich habe einen String der sieht so aus:

    20081008100803;baro_rs;1014.4;14.4;0;0;176;S;86;0;no;0.9;185;0.25;7.87;824.48;6;45

    Ich brauche die Werte zwischen den ";" ich hatte mir gedacht mit strtok zu teilen ...

    Das sieht aber ganz danach aus, als ob das eine "Zeile" wäre ... also der klassische Fall für Objektmember....
    Container sind für gleichartige Objekte und ich glaube nicht, dass mit "20081008100803" einfach nur ein anderer Wert für dasselbe Ding ist wie "baro_rs".

    übrigens: Statt strtok() (und vermutlich char[]) würde ich string(&stringstream) und seine Möglichkeit nutzen.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    ich glaube nicht, dass mit "20081008100803" einfach nur ein anderer Wert für dasselbe Ding ist wie "baro_rs".

    Nene die beiden haben nichts miteinander zu tun.

    Hab jetzt mal das mit dem Boost.Any probiert. Ich habe jetzt nur das Problem das wenn ich den Wert ausgeben will eine Fehlermeldung kommt. Siehe unten

    wetter.hpp

    #include <string>
    #include <list>
    #include <curl/curl.h>
    #include <boost/any.hpp>
    
    using namespace std;
    using namespace boost;
    
    class wetter
    {
    	public:    
    		// Methoden
    		wetter(); // Konstruktor    
    		static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);  
    		void parse();
    		void update();
    		~wetter(); // Destruktor
    
    		// Attribute
    		static string WetterString;
    		list<any> wetterdaten;
    		string url;
    		CURL *curl;
    };
    

    wetter.cpp

    #include <string>
    #include <iostream>
    #include "wetter.hpp"
    
    using namespace std;
    
    wetter::wetter()
    {
    	// Aufsetzen von Curl
    	url = "http://stringiminternet.de";
    	curl = curl_easy_init();
    	if(curl) {
    		curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wetter::write_data); 
    		curl_easy_perform(curl);
    	}
    
    	string Jahr, Monat, Tag, Stunde, Minute, Sekunde;
    	string Luftdrucktendenz;
    	/* 
    	Luftdrucktendenz:
    		baro_fr (Falling Rapidly)
    		baro_fs (Falling Slowly)
    		baro_s (Steady)
    		baro_rs (Rising Slowly)
    		baro_rr (Rising Rapidly)
    		baro_none (n/A)
    	*/
    	float Luftdruck; // in hPA
    	float Aussentemperatur;
    	float Windgeschwindigkeit;
    	float Wind_Schnitt;
    	short Windrichtung_Grad; // Grad
    	string Windrichtung;
    	short Regenrate;
    	bool Regen; // 1=Ja 0=Nein
    	float UV;
    	float Sonneneinstrahlung; // in Watt/qm^2
    	float Regen_Heute; // Heute
    	float Regen_Monat; // Monat
    	float Regen_Jahr; // Jahr
    	float Evapotranspiration_Heute; // Heute
    	float Evapotranspiration_Monat; // Monat
    
    	// Füge die Daten in die Liste hinzu
    	wetterdaten.push_back(Jahr);
    	wetterdaten.push_back(Monat);
    	wetterdaten.push_back(Tag);
    	wetterdaten.push_back(Stunde);
    	wetterdaten.push_back(Minute);
    	wetterdaten.push_back(Sekunde);
    	wetterdaten.push_back(Luftdrucktendenz);
    	wetterdaten.push_back(Luftdruck);
    	wetterdaten.push_back(Aussentemperatur);
    	wetterdaten.push_back(Windgeschwindigkeit);
    	wetterdaten.push_back(Wind_Schnitt);
    	wetterdaten.push_back(Windrichtung_Grad);
    	wetterdaten.push_back(Windrichtung);
    	wetterdaten.push_back(Regenrate);
    	wetterdaten.push_back(Regen);
    	wetterdaten.push_back(UV);
    	wetterdaten.push_back(Sonneneinstrahlung);
    	wetterdaten.push_back(Regen_Heute);
    	wetterdaten.push_back(Regen_Monat);
    	wetterdaten.push_back(Regen_Jahr);
    	wetterdaten.push_back(Evapotranspiration_Heute);
    	wetterdaten.push_back(Evapotranspiration_Monat);
    }
    
    string wetter::WetterString = "";
    
    size_t wetter::write_data(void *buffer, size_t size, size_t nmemb, void *userp)
    {
    	char *zeichenkette = (char*)buffer;
    	wetter::WetterString = zeichenkette;
    	return 0;
    }
    
    void wetter::parse()
    {
    	list<any>::iterator it;
    	it = wetterdaten.begin();
    
    	// Sonderbehandlung für den Zeitsempel
    	string Zeitstempel = WetterString.substr (0, 14);
    	*it = Zeitstempel.substr (0, 4);
    	cout << *it << endl;  // <--------- HIER !!!!!!!!!!
    
    	// Lösche den Zeitstempel am Anfang des Strings
    	int pos = WetterString.find(";");
    	WetterString.erase(0, pos+1);
    
    }
    
    void wetter::update(){
    	curl_easy_perform(curl);	
    }
    
    wetter::~wetter()
    {
    	// Curl beenden
    	curl_easy_cleanup(curl);
    }
    

    g++ -Wall -lcurl -lgssapi_krb5 -I /usr/include/boost -o wetter wetter.cpp main.cpp
    wetter.cpp: In member function »void wetter::parse()«:
    wetter.cpp:101: Fehler: no match für »operator<<« in »std::cout << it.std::_List_iterator<_Tp>::operator* [with _Tp = boost::any]()«
    /usr/include/c++/4.2/ostream:112: Anmerkung: Kandidaten sind: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& ()(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:121: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>& (
    )(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:131: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& ()(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:169: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:173: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:177: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/bits/ostream.tcc:92: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:184: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/bits/ostream.tcc:106: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:195: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:204: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:208: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:213: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:217: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:225: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/ostream:229: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void
    ) [with _CharT = char, _Traits = std::char_traits<char>]
    /usr/include/c++/4.2/bits/ostream.tcc:120: Anmerkung: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]

    Bitte beachtet das ich noch Anfänger bin, ich glaube das habt ihr aber sicher schon gemerkt...



  • Mitbewohner schrieb:

    Simon2 schrieb:

    ich glaube nicht, dass mit "20081008100803" einfach nur ein anderer Wert für dasselbe Ding ist wie "baro_rs".

    Nene die beiden haben nichts miteinander zu tun.

    Und da sie allesamt benannt sind und einen Sinn haben, solltest du lieber daraus eine ganz normale Klasse mit ganz normalen Membern machen. Der Schreibaufwand mag zwar höher sein, aber anderseits bleibt das Programm auch später noch verständlich und Wartungsfreundlich. Gerade der Fall den du Zeigst ist eigentlich ein Fall wo man gerade nicht auch brechen und würgen mit Varianttypen arbeitet.



  • Mitbewohner schrieb:

    Simon2 schrieb:

    ich glaube nicht, dass mit "20081008100803" einfach nur ein anderer Wert für dasselbe Ding ist wie "baro_rs".

    Nene die beiden haben nichts miteinander zu tun....

    ...und genau dafür hat der liebe Gott C++ so gemacht, dass unterschiedliche Dinge auch unterschiedliche Namen haben können.
    => 2 Variablen (sei es nun in einem gemeinsamen struct oder nicht)
    Du würdest doch auch nicht versuchen, für Schuhe und 1 Hektoliter Öl denselben Behälter zu verwenden.

    Gruß,

    Simon2.



  • ...und genau dafür hat der liebe Gott C++ so gemacht...

    Ach.. und ich dachte immer das sei der andere Typ mit dem komischen Bart und halbglatze gewesen.. :p



  • drakon schrieb:

    ...und genau dafür hat der liebe Gott C++ so gemacht...

    Ach.. und ich dachte immer das sei der andere Typ mit dem komischen Bart und halbglatze gewesen.. :p

    Na - das war halt der damit beauftragte Fachingenieur... 😉

    Gruß,

    Simon2.


Anmelden zum Antworten