[C++] Datenstream Frage auslesen von Datei

max28

Grünschnabel

Einen schönen guten Abend zusammen.
Vielleicht kennt noch jemand das etwas ältere Spiel "Alien vs. Predator2".
Ich arbeite z.Z. an einem kleinen Programm, welches einem die Handhabung mit den *.rez
Dateien vereinfachen soll.
Theoretisch funktioniert mein Programm schon, allerdings wird es sicherlich viele Fehler haben und teilweise umständlich programmiert sein, da dies mein erstes wirkliches C++ Programm ist und ich hab mir alle Funktionen mehr oder weniger aus dem Internet zusammengesucht.
Mein Programm musste ich in 2 kleine Programme aufteilen, das erste ist dafür da eine Konfigurationsdatei zu erstellen, in Form eines *.ini Dokumentes.
Und das 2. Programm liest die Konfigurationsdatei aus, speichert den Inhalt in einer Variabel und fügt es als Parameter zu einem längeren Befehl hinzu, mit welchem dann letztendlich das Spiel gestartet werden soll.
Soweit funktioniert es. Allerdings ist diese Form nicht wirklich benutzerfreundlich, schöner wäre es lediglich ein Programm zu haben, welches den Benutzer beim ersten ausführen (oder wenn die config Datei leer ist) fragt, ob er eine neue erstellen möchte.
Wenn die Konfigurationsdatei angelegt wurde (wobei jeder mögliche Parameter eine Zeile darstellen soll) wäre es praktisch wenn der Benutzer beim abermaligen Start des Programmes, ein Auswahlmenü angeboten bekommt, welchen Parameter, sprich welche Zeile er mit dem Spiel laden möchte, oder ob er das Spiel ohne weitereParameter starten möchte.
Ich glaube das hört sich alles viel komplizierter an, als es eigentlich ist.
Leider weiß ich viele Sachen nicht, wie z.B. lese ich einzelne Zeilen aus einer Textdatei, oder wie erstelle ich ein funktionierendes Auswahlmenü mit case / switch Anweisungen.

Hier mal der Code meiner beiden Programme, ich bin für jeden Tip dankbar.
Vielen Dank schonmal und schönen Gruß:
Max

Code:
#include <windows.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <conio.h>
using namespace std;

int main (int argc, char *argv[])
{
     FILE* config; 
    config = fopen("config.ini", "a");
    fclose(config);

       char inc[55];

	cout<<"Konfigurationseditor -\n\n";
	cout << "Bitte kompletten *.rez Namen angeben der automatisch mit geladen werden soll \nz.B. \"-rez avp2league.rez -rez test.rez\"\noder \"-rez maps -rez custom/blah.rez.\"\nENTER um das Programm zu beenden.\n\nDeine Eingabe: ";
	cin.get (inc, 54);

    fstream f;
    f.open("config.ini", ios::out);
    f << inc << endl;
   	f.close(); 

    return 0; 
}
Code:
#include <windows.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <conio.h>
using namespace std;

int main (int argc, char *argv[])
{

    FILE* config; 
    config = fopen("config.ini", "a");
    fclose(config);

    std::fstream FStream; 
    FStream.open ("config.ini", std::ios::in); 
	
	    /* Überflüssige Fehlerroutine?
	if (!FStream) {
		cout << "Config Datei nicht gefunden...\nDruecke Taste um das Programm zu beenden." << ends;
		getch(); exit(2);  } */
	
    { 
        FStream.seekg(0, std::ios::end); 
        unsigned long FileSize = std::streamoff(FStream.tellg()); 
        FStream.seekg(0, std::ios::beg); 

        char *Buffer = new char [FileSize+1]; 
		
		    // Ganze Zeile in das char-Array
        FStream.getline(Buffer,FileSize);

		    // Wenn Zeile leer ist ...
	    if (FileSize == 0) {
	
			// menu
		cout<<"- Loader -\n\n";
		cout<<"Es wurde keine Konfiguration gefunden... \n";
		cout<<"bitte Configurator starten.\n\n";
		cout<<"Programm verlassen: ";
	    getch(); exit(2);  } 

        Buffer [FileSize] = '\0'; 
        FStream.close ()

	ostringstream os;
		os << "lithtech.exe" << " -windowtitle \"avpII\" -rez AVP2 -rez AVP2.REZ -rez SOUNDS.REZ -rez AVP2L.REZ -rez AVP2DLL.REZ -rez AVP2P.REZ -rez AVP2P1.REZ -rez MULTI.REZ -rez ALIEN.REZ -rez MARINE.REZ -rez PREDATOR.REZ "  << " " << Buffer << " +DisableMusic 0 +DisableSound 0 +DisableMovies 1 +DisableJoystick 1 +EnableTripBuf 1 +DisableHardwareCursor 0";

		    // Programm mit Parametern starten
		system( os.str().c_str() ); 

		    /* Gesamten ostreamstring ausgeben
		cout << os.str().c_str(); */

        delete [] Buffer; 
    } 

    return 0; 
}
 
Zuletzt bearbeitet:
Hi.

Ganz trivial könntest du dein Problem natürlich lösen indem du eine der main Funktionen umbenennst, z.B. die erste in "int edit_config (void)" und diese dann einfach in dein anderes Programm einfügst und aufrufst wenn die Datei noch nicht existiert.

Allerdings benutzt du sowohl die fopen Funktion der C Bibliothek als auch die C++ I/O Streams. Ich finde du solltest dich für eine Methode des Dateizugriffs entscheiden. In C++ würde ich auf jeden Fall die I/O Streams bevorzugen und nur in Ausnahmefällen auf die C Bibliotheksfunktionen zurückgreifen.

Um die Zeilen von der Datei einzulesen benutzt du besser einen string. Und du solltest immer auch überprüfen ob etwas eingelesen werden konnte.

Code:
const string file_name = "config.ini";

string user_config;

fstream ini_file (file_name, ios::in);

if (ini_file.is_open ()) {
  if (!getline (ini_file, user_config)) {
    cerr << "ungültige Konfigurationsdatei.\n";
    user_config = edit_config (file_name);
  }
} else {
   user_config = edit_config (file_name);
}

string cmdline = "lithtech.exe -windowtitle \"avpII\" -rez AVP2 -rez AVP2.REZ -rez SOUNDS.REZ -rez AVP2L.REZ -rez AVP2DLL.REZ -rez AVP2P.REZ -rez AVP2P1.REZ -rez MULTI.REZ -rez ALIEN.REZ -rez MARINE.REZ -rez PREDATOR.REZ  ";

cmdline += user_config;
cmdline += " +DisableMusic 0 +DisableSound 0 +DisableMovies 1 +DisableJoystick 1 +EnableTripBuf 1 +DisableHardwareCursor 0";

Code:
string edit_config (const string& file_name) {
  fstream ini_file (file_name, ios::in | ios::out | ios::trunc );
  string input;

  if (ini_file.is_open ()) {
    cout<<"Konfigurationseditor -\n\n";
    cout << "Bitte kompletten *.rez Namen angeben der automa..." 

    if (getline (cin, input)) {
      ini_file << input << endl;
    } else {
      /* keine Eingabe vom User? */
    }
  } else {
    cerr << "Konnte Datei nicht erstellen: " << file_name << endl;
  }
  return input;
}

Für den Code gibt's natürlich keine Gewähr ;) Aber evtl. bringt er dich ja auf Ideen wie du deinen Code noch etwas verbessern kannst.

Gruß
 
super vielen Dank, das bringt mich auf jeden Fall weiter.
Ich werd mich da mal durchschauen ;)

So, ich hab mir das mal angesehen.
Dein Vorschlag mit den Funktionen war sehr gut, und nach einigem rumprobieren hat es dann auch geklappt.
Allerdings möchte ich einmal den vom Benutzer gewünschten Parameter in einer Variabel speichern und zusätzlich noch einen Namen für den jeweiligen Parameter, damit der Benutzer nachher weiß welchen Parameter er mit laden möchte.
Ich weiß leider nicht, wie ich das bewerkstelligen kann.
Wäre es dir möglich mir vielleicht noch einen Anhaltspunkt dafür zu geben?
Hier ist mein bissheriger code
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include "ic.h"

std::fstream FStream;

std::string edit_config(std::string input)
{
	std::fstream f;
	std::string param_name1, param_name2, param_name3;
	
	    // Datei zum einlesen öffnen
	FStream.open ("config.ini", std::ios::in);
	    // Prüfen ob Datei vorhanden ist
	if (FStream.good());
	if (FStream.is_open ()) 
	  {
	    FStream.close();
        std::cout << "Es koennen maximal 3 Konfigurationen gespeichert werden." << std::endl << std::endl;
		std::cout << "Gebe den ersten Parameter an: ";
		std::getline (std::cin, input);
		f.open("config.ini", std::ios::out);
	    f << input << std::endl;
		std::cout << "Name des Parameters: ";
		//std::getline (std::cin, param_name1);
		//f << param_name1 << std::endl;
		 }
		 
   return input;
 }
 
int main (int argc, char *argv[])
{	
	std::string input;
	
	    // Konsolentitel setzen
	con.setTitle("crezLoader & NoCD Patch");
	    // Konfiguration öffnen
	FStream.open ("config.ini", std::ios::in);
	if (FStream.good());
	if (!FStream)
	  {
	    std::cout << "Konfigurationsdatei nicht gefunden..." << std::endl;
		getch();
		exit(2);
	   }
	    // Dateigröße bestimmen
	FStream.seekg(0, std::ios::end); 
	unsigned long FileSize = std::streamoff(FStream.tellg()); 
	FStream.seekg(0, std::ios::beg);
	    // Buffer erstellen
	char *inhalt = new char [FileSize+1];
	    // Ganze Zeile einlesen
    FStream.getline(inhalt,FileSize);
        // Wenn Zeile leer ist
    if (FileSize == 0)
    { 
	  FStream.close();
      std::cout << "Input = " << edit_config(input) << std::endl;
	  getch();
	 }
	else
	    {      
		   std::cout << "Konfigurationsdatei ist nicht leer." << std::endl;
		   getch();
		 }
	
  return 0;	
 }
Es wär auch nett, wenn mir jemand sagen könnte ob das alles auch syntaktisch ordentliches c++ ist, oder ob ich daran etwas verbessern kann.
Vielen Dank.
 
Zuletzt bearbeitet:
Zurück