Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 20 von 37

Thema: Konfigurationsdateien in C++

  1. #1

    Konfigurationsdateien in C++

    Hiho^^,
    ich bin grad dabei mein erstes eigenes Programm (wenn man die "Projekte" aus der Ausbildung mal ausser Acht lässt) zu erstellen. Dieses soll sich auch einige Dinge merken (Pfadangaben und evtl. andere Einstellungen).
    Jetzt frag' ich mich, wie ich am Besten eine Konfigurationsdatei erstelle und die im Nachhinein wieder richtig auslese.
    Das Schreiben in und das Lesen aus Dateien sollte dabei das geringere Übel sein.
    Nur irgendwie müsste ich die geschriebenen Werte ja den Variabeln im Programm zuordnen...

  2. #2
    Ich würd mir INI oder XML Routinen suchen/schreiben. Für den Anfang ist INI allerdings leichter, wobei XML logischerweise ne Menge mehr kann.

  3. #3
    Und nach der Methode:

    Zeichenfolge im Stream (Datei) suchen und den Wert, der danach Folgt, auslesen.

    geht's nicht?

    Ich hab mich (heute Nacht) mal mit dem Thema .ini "rumgeschlagen". Ganze Parser findet man da... wieso muss das alles immer so komplex und aufgeblasen sein?^^
    Eine ganz simple Konfig... mehr will ich doch garnicht^^ (für V1 meines Programms...sagt ja keiner, dass es nicht komplexer werden darf)

  4. #4
    Wo ist das Problem? Einfach die Datei öffnen und beispielsweise mit fscanf() auswerten. Schon hast du die Informationen aus der Datei.
    PS: Ist allerdings waschechtes C.

    freundliche Grüße, Rolus

    Geändert von Rolus (15.08.2006 um 23:13 Uhr)

  5. #5
    Entweder du arbeitest an einer Stelle die ganze Datei ab und setzt entsprechend alle deine Variablen, oder du arbeitest jedes mal, wenn du einen speziellen Wert aus der Datei brauchst, die Datei zeilenweise ab, bis du den Wert findest, den du benoetigst, oder (die bessere Variante) du liest die ganze Datei in einen Speicherblock ein und roedelst dann auf dem Speicherblock an Stelle der Datei rum.

    Was ist genau dein Problem ? Das Ein-/Auslesen, das Finden eines bestimmten Bezeichners und seines Wertepaares, oder die Verwaltung deiner Variablen ?

  6. #6
    Mein Problem ist momentan das Lesen und Schreiben in Dateien... ich hab' das zwar schonmal gemacht (ergo: Ich wusste mal wie's geht^^)... aber irgendwie wills mit "ofstream" und "ifstream" nicht so recht werden... es sei vielleicht dazu gesagt, dass ich den CBuilder1 verwende (von der Ausbildung aus).

  7. #7
    Du kannst wenn du nur Windows verwendest scheinbar auf WinAPI Funktionen zurückgreifen: http://www.c-plusplus.de/forum/viewt...-is-39388.html (2. letzter Post) oder wenn du es selbst machen willst kannst du dir ja mal http://c.snippets.org/snip_lister.php?fname=ini.c ansehen.

  8. #8
    Zitat Zitat
    wenn du es selbst machen willst kannst du dir ja mal http://c.snippets.org/snip_lister.php?fname=ini.c
    Ziemlich derbes C^^
    Ist ja schon größer als mein Projekt^^

  9. #9
    Schau dir einfach mal die Funktionsweise von fscanf() an. Wird zum Beispiel hier erklärt. Damit kannst du deine Konfigurationsdatei recht schnell selbst auswerten, ohne unnötig viel fremden Code nutzen zu müssen. Geht dann so nach dem Prinzip:
    Code:
    char path[96];
    FILE * file;
    file = fopen ("config.ini","r");
    fscanf (file, "Pfad=%s\n", &path);
    freundliche Grüße, Rolus

    Geändert von Rolus (15.08.2006 um 23:13 Uhr)

  10. #10
    thx, endlich mal eine Seite, die mir weiterhilft. Obwohl diese "ini.c" an sich ja nicht schlecht ist. Für dieses (noch) kleine Projekt aber wohl (noch) zu viel.
    Reine Frage aus interesse... eine Konversion des Ganzen nach C++?
    Und: muss ich was beachten, wenn ich mit AnsiStrings arbeite?

  11. #11

    Users Awaiting Email Confirmation

    Eine Konversion in C++ ist ja gar nicht notwenig, da du es einfach so in einem C++ Programm benutzen kannst. Zudem ist mir keine C++ Funktion wie fscanf bekannt, aber das hat nicht unbedingt was zu sagen.

    Bei Ansistrings gibt es nicht viel zu beachten. Probier mal aus, ob statt dem Character-Array auch ein Ansistring funktioniert, wenn nicht kannst du den Charakter Array ja einfach in einen Ansistring umformen:

    Code:
      std::string cppstring;
      char cstring[80];
    
      strcpy (cstring, "Hallo Welt");
      cppstring = cstring;
      
      std::cout << cppstring << std::endl;
    Du solltest vielleicht noch beachten, am Ende nochmal fclose zu benutzen, damit es auch vollständig ist.

    Gruß, Micha <><

  12. #12
    So~,
    hab' mich heute, nach se~hr langer Zeit, mal wieder an das Programm gesetzt und die paar Zeilen "eingehackt", wie mein Lehrer zu sagen pflegt.
    Es funktioniert zwar alles, ich möchte dennoch sichergehen, dass ich da keinen Schwachsinn geschrieben habe. Ausserdem gefallen mir die beiden Char-Arrays beim Auslesevorgang nicht. Wegbekommen kann ich sie allerdings auch nicht. Vielleicht hab' ich was übersehen?

    Hab's übrigens erstmal in ein Testprogramm geschrieben. Also nicht wundern...

    .cfg schreiben:
    Code:
    void __fastcall TForm1::WriteBtnClick(TObject *Sender)
    {
      FILE *cfg;	
      AnsiString path;
      path = PathEdt->Text;
      cfg = fopen("emp.cfg", "w+");
      fprintf(cfg, "path = %s\n", path);
      fclose(cfg);
    }
    .cfg auslesen:
    Code:
    void __fastcall TForm1::ReadBtnClick(TObject *Sender)
    {
      FILE *cfg;
      char varValue[255], varName[255];
      AnsiString path;
      cfg = fopen("emp.cfg", "r");
      fscanf(cfg,"%s = %s\n", varName, varValue);
      path = varValue;
      PathLbl->Caption = path;
      fclose(cfg);
    }
    'varName' und 'varValue' existieren eigentlich, damit ich später die einzelnen Variablen in der .cfg erkennen kann. Aber irgendwie klappte die Abfrage bist jetzt noch nicht (hatte es mit einem 'if' versucht...)

  13. #13
    Hm, sieht ja echt borländisch aus, dein Code. Aber der Code geht eigentlich einigermaßen, wenn man mal davon absieht, dass du C und C++ wild mischst. Ist zwar nicht verboten, aber dann musst du wohl auch mit Char-Arrays arbeiten. Du könntest dich natürlich auch für pures C oder C++ entscheiden. Das heißt z.B. wenn du dich für C++ entscheidest, dass du für die Dateioperationen die fstream-Methoden nutzt. Also das Erstellen könnte z.B. so aussehen (vom Prinzip her):
    Code:
    #include <fstream>
    using namespace std;
    // ...
    void __fastcall TForm1::WriteBtnClick(TObject *Sender)
    {
     ofstream outfile("emp.cfg");
     outfile << "path " << PathEdt->Text << endl;
    }
    Und das einlesen etwa so:
    Code:
    void __fastcall TForm1::ReadBtnClick(TObject *Sender)
    {
     AnsiString varName,path;
     ifstream infile("emp.cfg");
     infile >> varName; // hier wird "path" gelesen (bis zum Leerzeichen)
     infile >> path; // hier der tatsaechliche Pfad
     PathLbl->Caption = path;
    }
    Allerdings kann's sein, dass Borlands C++ Builder da noch seine speziellen Eigenarten hat.

    freundliche Grüße, Rolus

    Geändert von Rolus (15.08.2006 um 23:39 Uhr)

  14. #14
    Mal sehen, ob ich das so umgeschrieben bekomme (sollte das kleinere Übel sein).
    Nun ist mir leider was Anderes aufgefallen. Bekommt eine Variable einen Pfad per Öffnen-Dialog (ich weiß nicht, ob Borland da über die WinAPI geht) kann ich die zumindest mit
    Code:
    fprintf(cfg, "path = %s\n", varValue)
    nicht schreiben. Trag' ich den Pfad von Hand ein geht's. Jedoch nach dem Versuch den per Öffnen-Dialog übergebenen Pfad zu speichern, schlägt auch die Handeingabe fehl (sprich er erstellt keine Datei bzw. überschreibt die Alte nicht). Irgendwas muss da ja (aufgrund eines unsichtbaren (halt ungültigen) Zeichens, was weiß ich) blockieren.
    Hatte mich zunächst geärgert und gewundert, da es im Testprogramm 1A funktionierte. Da hatte ich den Pfad auch nur per Hand übergeben, was wohl mein Fehler war...
    Irgendwelche Ideen?

  15. #15
    Zitat Zitat von Junta
    (ich weiß nicht, ob Borland da über die WinAPI geht)
    Letztendlich sicher, eine andere Möglichkeit hat Borland ja gar nicht.
    Zitat Zitat von Junta
    Jedoch nach dem Versuch den per Öffnen-Dialog übergebenen Pfad zu speichern, schlägt auch die Handeingabe fehl (sprich er erstellt keine Datei bzw. überschreibt die Alte nicht). Irgendwas muss da ja (aufgrund eines unsichtbaren (halt ungültigen) Zeichens, was weiß ich) blockieren.
    Hatte mich zunächst geärgert und gewundert, da es im Testprogramm 1A funktionierte. Da hatte ich den Pfad auch nur per Hand übergeben, was wohl mein Fehler war...
    Irgendwelche Ideen?
    Ja, sieht ganz so aus, als ob bei dem Dialog das Problem liegen würde. Also würde ich mir mal die Dokumentation zu der entsprechenden Funktion anschauen, damit du siehst, ob du den Dateinamen richtig abfragst. Ansonsten poste mal den entsprechenden Code.

    freundliche Grüße, Rolus

  16. #16
    Die WinAPI stellt zum oeffnen, lesen, schreiben und bearbeiten von Dateien saemtlich eigene Funktionen zur Verfuefung. Wenn du also Dateinamen jenseits von 8.3 Zeichen verwenden willst, solltest du nicht die standard C-Funktionen unter Windows nutzen, sondern die Dateifunktionen und -handler der WindowsAPI, vor allem, wenn du ohnehin schon sowas wie den Oeffnen-Dialog von Windows verwendest. Als alte Faustregel gilt, mische so wenig wie moeglich Code von verschiedenen Quellen, d.h. fprintf/<< fuer die Console und CreateFile/OpenFile/ReadFile/WriteFile fuer WindowsAPI GUIs.

    Ich bin damit auch mal auf die Nase geflogen ...

  17. #17
    Also, fang' ich mal von Vorne an.
    Den Dialog hatte ich ja auch schon als "Fehlerquelle" ausgemacht. Die CBuilder Doku sagt dazu ja Folgendes:
    Zitat Zitat
    Header

    vcl/dialogs.hpp
    TOpenDialog erzeugt ein Dialogfeld, in dem der Benutzer eine Datei auswählen kann.

    Beschreibung

    TOpenDialog erzeugt ein Windows-Dialogfeld, in dem der Benutzer eine Datei auswählen und öffnen kann. Das Dialogfeld wird zur Laufzeit erst angezeigt, wenn es mit der Methode Execute aktiviert wird. Wenn der Benutzer auf öffnen klickt, wird das Dialogfeld geschlossen, und die ausgewählten Dateien werden in der Eigenschaft File gespeichert.
    Wobei die Eigenschaft 'File' nicht existiert sondern nur 'FileName'.
    Geöffnet und abgefragt wird der Öffnen-Dialog bei mir folgendermaßen:
    Code:
    void __fastcall TMainForm::ChangePathBtnClick(TObject *Sender)
    {
    	OpenDlg->Filter = "Ausführbare Dateien | *.exe";
    	if(OpenDlg->Execute());
    	{
    		PathEdt->Text = OpenDlg->FileName;
    		playerPath = PathEdt->Text;
    	}
    }
    Stand, glaube ich, sogar so in der beiliegenden Hilfe.

    @ine
    Eigentlich hatte ich vor, so weit weg von der WinAPI zu arbeiten wie möglich. Was mir schon mit der verwendung von 'ShellExecute()' leider nicht geglückt ist (gibts einen anderen Weg ausser über 'system()'?). Ich möchte das Programm später eventuell mal auf Linux testen(weiß nich nicht mal, wie ich mir da die Oberfläche zusammenschnibbeln muss).

    Ich hatte ja ausserdem selbst nicht vor verschiedenen Code zu mischen und fragte daher auch schon dach einer vergleichbaren Funktion von 'fprintf()' und 'fscanf()' in C++.

    Zudem wollte ich eigentlich nur zur Übung abseits der Ausbildung ein Programm schreiben, da ich mich mit Programmieren ansonsten wohl nie beschäftigen würde (leider bin ich irgendwie noch nicht so weit, dass ich mich einfach vor ein gutes, das Thema betreffende, Buch setze anstatt drauf los zu Programmieren).

  18. #18
    Wenn du portabel arbeiten willst, dann ist der Borland CBuilder eine gaaaaanz schlechte Wahl. Borland CBuilder ist zu C(++) das selbe, was Delphi zu ObjectPascal ist.

    Fuer Portabilitaet empfehle ich einzig und allein die GCC und ein unabhaengiges GUI Toolkit. Borland CBuilder und Windows ist praktisch untrennbar.

  19. #19
    Ich weiß, das habe ich schon zu Ausbildungsbeginn von meinem Lehrer erfahren. Deswegen schrieb ich ja auch, dass ich noch nicht weiß, wie ich mir da die Oberfläche zusammenbauen soll. Auf'm Amiga haben die das mit einem extra Editor gelöst. Die damit erstellte Datei ließ sich einfach in's Projekt einbinden.
    (Memo an mich: am Programm weiterarbeiten.)

    Das problem mit dem Öffnen-Dialog besteht übrigens auch bei Verwendung von 'ofstream'. Oder ich mach' einfach irgendwas falsch.

    Geändert von Junta (17.08.2006 um 05:48 Uhr)

  20. #20
    Schau dir doch einfach einmal GTK an. Das ist eine wunderschoene objektorientierte API in C geschrieben, die ziemlich plattformunabhaengig ist. Die Lizens ist auch ziemlich entwicklerfreundlich.


    btw ist der ifstream und der ofstream in fstream zusammengefasst.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •