String zu Variable

finke

finke

Eroberer
Hi, ich hab folgendes Problem, ich möchte mit c++ eine klasse schreiben, welsche eine config-Datei mit folgendem Syntax einliest.
Code:
# Zeilen die mit # beginnen sind Kommentarzeilen.
# Variablen werden vollständig groß geschrieben.
# 
# Werte werden  wie folgt angegeben:
# FOO = Zahl   Übergibt die Zahl zahl
# FOO = On     Schaltet die Option an
# FOO = Off    Schaltet die Option aus
# FOO = "foo"  Übergibt den String 'foo'

Jetzt soll für jede in der Datei stehende Option in der Klasse eine Variable mit dem entsprechendem Namen, und typ erstellt werden. Ist sowas überhaupt möglich?
Und genau so, kann ich mit
Code:
string get_config(string config);
int set_config(string config, int value);

eine variable ansprechen? das praktisch der string config als Variablenname in der Funktion verwendet wird?
 
kenn mich nicht so mit c++ aus,
in Perl würde ich einen hash benutzen, was wohl auch als assoziatives array bekannt ist.
dann hättest sowas wie
$config{FOO}="bar";
über den index kannst dann die verschiedenen Werte ansprechen. Kannst ja nach sowas in c++ suchen.
 
okar schrieb:
$config{FOO}="bar";
über den index kannst dann die verschiedenen Werte ansprechen. Kannst ja nach sowas in c++ suchen.
In C++ wuerde man das mit einer std::map<std::string, std::string> oder einer multimap machen. Ist es das, was Du suchst?

Falls die Variablen alle die gleiche Struktur haben, kannst Du auch eine Klasse 'Variable' entwerfen, die die Attribute (einschliesslich einer ID) enthaelt. Die verschiedenen 'Variable's kannst Du dann in einem vector oder auch wieder einer map<string, Variable> speichern. Das koennte das Abarbeiten der Variablen erleichtern, haengt jedoch davon ab, was Du damit vorhast.
 
Zuletzt bearbeitet:
Was ich vorhabe, ist, das die Klasse beim erstellen einer Instanz die Datei einließt, Zeile für Zeile durchgeht, Komentar- und Leerzeilen überspringt, und den Rest (zB: "MIN_GUILP_PLAYER = 5"), in 3 teilstrings teilt, "MIN_GUILP_PLAYER", "=", "5".
Jetzt soll er durch vergleiche herausfinden, von welschem typ das letzte stück ist, bei "On", "Off" bool, bei '"....."' string, "1234567890" int.
Anschließend soll er in der Klasse ne Variable mit dem namen "MIN_GUILP_PLAYER " vom Typ int anlegen, und ihm die zahl 5 zuweisen.
das geht solange, bis das Dateiende erreicht ist, als letztes wird dann die datei geschlossen.

Jetzt frag ich mich ob man das überhaupt so einfach realisieren kann, oder ob ich bei jeder Erweiterung der Config auch den Quellcode erweitern muss.
 
Zuletzt bearbeitet:
Also das Parsen der Datei sollte nicht so das Problem werden, genausowenig das Feststellen obs ein reiner Integer-Wert ist oder ein Chararray, aber du kannst doch nicht einfach nach dem Kompilieren dynamisch Variablen innerhalb einer Klass erzeugen, oder irre ich mich?
Und selbst wenn, wie und wann greifst du dann auf diese zu? (Dieses Problem wäre in interpretierten Sprachen auch noch existent, wobei der Rest in perl zum Beispiel recht trivial wäre.)

Klingt irgendwie ein Bisschen abenteuerlich. Aber vielleicht hab ich ja auch nur ein zwei Sachen falsch verstanden..
 
Wenn ich dich richtig verstanden habe, möchtest du während der Laufzeit neue Variablen deklarieren. Das ist grundsätzlich aber nicht möglich. Für solche Fälle greift man zur dynamischen Speicherverwaltung. D.h. dass du während der Laufzeit neuen Speicher reserviest, wenn er benötigt wird. Realisieren lässt sich das über Pointer.

Es gibt verschiedene Möglichkeiten, wie du das programmieren kannst (z.B. verkettete Listen). Hier mal ein Link, vielleicht hilft dir das weiter:

http://www.galileocomputing.de/openbook/c_von_a_bis_z/c_016_001.htm

Ansonsten musst du mal google bemühen
 
Wenn du eine Config Datei für ein bestimmtes Programm schreiben willst, geh ich mal davon aus, dass jede Variable die du in einer config datei deklarierst auch irgendwo in deinem Programm vorkommen wird. Davon ausgehend würde ich folgendes machen:

Alle Variablen, die benötigt werden, sollten in deiner Parserklasse deklariert sein und in deinem Konstruktor mit default werten initialisiert werden. Aus deiner Config Datei kannst du dann mit den Funktionen get_config() und set_config() deine Variablen beliebig setzen. Du benötigst halt eine gewisse "Norm" für deine Variablen.

Solltest du andererseits tatsächlich die Variablen "dynamisch" deklarieren und initialisieren wollen würd ich auch eher an andere Datenstrukturen wie Listen u.ä. denken.
 
Die Variablen bereits in die KLasse zu schreiben, war ebend auch mein erster Gedanke, wollt nur fragen, ob es auch dynamisch geht, da dann eine Korrektur der Klasse nach einer Veränderung in der config entfallen würde. werde das jetzt erstma statisch machen.
 
So, hab jetzt ma angefangen, die Klasse zu schreiben. Hab ma alle Datein (.conf, .hpp, .cpp) hoch geladen.

Ich hab jetzt das Problem, wie bekomme ich jetzt "value" in die Variable "string".

Hinweise zu Fehlern und Optimierungsvorschläge ausdrücklich erwünscht.
 
Zuletzt bearbeitet:
hm... sehr komische herangehensweise würd ich sagen.

Zum einen würde ich den member get_config(string var) nicht überladen. Als Returnwert würd ich da lieber ein boolean nehmen und die Zuweisung zur Variable direkt in der Memberfunktion machen. Wär zumindest der Sinn einer Klasse. Den Bool kannst du dann verwenden um zu testen, ob die Variable zugewiesen wurde.

Die Werte kannst du mit den Funktionen atoi, atol,... von char* nach int, long, double konvertieren. Ob das aus nem String Objekt heraus funktioniert weis ich ned... evtl mit nem cast. Müsst ich nachschlagen und dafür bin ich jetz zu faul ;)

*just my 2 cents*
 
So, viele stunden Tipparbeit später, beginnt die Hoffnung in mir aufzublühen, die Klasse demnächst fertig zu stellen.
Ich habe vieles nochmal grundlegend überarbeitet, und hab nur noch 2 Fehler.

Ich hab nochmal alles hochgeladen, und Buildprotokoll von Windows und Linux beigelegt. Kann mir bitte wer helfen, die 2 Fehler zu beheben?
ich verstehe einfach net, warum
Code:
if(ergebnis = this->config_string[var])
und
Code:
if(config_string[var] = value)
zu Fehlern führt.
Code:
c:\dokumente und einstellungen\kristian\desktop\pog\read_server_conf.cpp(63) : error C2451: Bedingter Ausdruck des Typs 'std::basic_string<_Elem,_Traits,_Ax>' nicht zulässig
        with
        [
            _Elem=char,
            _Traits=std::char_traits,
            _Ax=std::allocator
        ]
        Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
c:\dokumente und einstellungen\kristian\desktop\pog\read_server_conf.cpp(89) : error C2451: Bedingter Ausdruck des Typs 'std::basic_string<_Elem,_Traits,_Ax>' nicht zulässig
        with
        [
            _Elem=char,
            _Traits=std::char_traits,
            _Ax=std::allocator
        ]
        Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
ergebnis, var, value sind vom typ string,
und config_string is als
Code:
map<string, string> config_string;
definirt.
 
Zuletzt bearbeitet:
Kann mir den echt garniemant bei den letzten 2 Fehlern helfen?
gibts nichma irgendwelche mecker oä. über meinen schlechten Stiel?
 
Assign ist kein Vergleich...

Da Du nicht vie Code publizierst, rate ich mal:

willst Du in Deinem Code vergleichen oder zuweisen?
Bei einem Vergleich:

if(ergebnis :devil:== this->config_string[var])
 
zuweisen,
Aber ich denk ma selbst bei vergleich würde dort der Konvertierungsfehler auftauchen, der dort in meinen Augen nicht hingehört, oder?
 
Zuletzt bearbeitet:
[OT]
finke bist du der finke von ProjektOG? Wenn ja dann mail ich dir noch was dazu
[/OT]
 
Das hat sich doch schon erledigt, war für die read_config Klasse, aber bei der ham sich doch die Anforderungen, die Technik und der Autor geändert.
 
Zuletzt bearbeitet:

Ähnliche Themen

NagiosGrapher 1.7.1 funktioniert nicht

nach einem String suchen und anschließend wert speichern

dovecot und postfix Konfiguration Problem

Last mit etc/passwd anzeigen lassen

Squid nur zum maskieren der eigenen IP, nicht für Webserver auf port 80

Zurück
Oben