Zeile aus Datei lesen



  • Hallo Community.
    Ich wollte heute meine cVar Klasse aktuallisieren.
    Im Moment lese ich wie gewöhnlich eine .ini Datei aus. Beispiel:

    [Overlay]
    overlay_interval = 1.50
    

    Mit meinem individuellen Konstruktor erstelle ich mir nun für jede einstellung eine Variable.

    #ifndef CVAR_H
    #define CVAR_H
    
    #define MAX_VARS 256
    
    #include <Windows.h>
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    class cVars
    {
    private:
    	int		iGetFirstVar;
    
    	struct cVars_t
    	{
    		char	*Name;
    		float	 flValue;
    		float	 flMinValue;
    		float	 flMaxValue;
    		string	 AppName;
    		string	 KeyName;
    		string	 Filepath;
    	};
    
    	cVars_t gVar[ MAX_VARS ];
    
    	int		GetFirstVar( );
    	int		GetVarEntry( char *_Name );
    
    	void	SetFirstVar( int _Value );
    
    	string	GetCurDir( );
    	float	GetPrivateProfileFloat( LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpFilePath );
    public:
    	void	StartUp( );
    	void	AddVar( char *_Name, float _flValue, float _flMinValue, float _flMaxValue, string _AppName, string _KeyName, string _Filepath );
    	float	GetValue( char *_Name );
    
    };
    
    extern cVars *cVar;
    
    #endif
    

    Und die passende .cpp Datei:

    #include "cVar.h"
    
    cVars *cVar = new cVars( );
    
    int cVars::GetFirstVar( )
    {
    	return this->iGetFirstVar;
    }
    
    int cVars::GetVarEntry( char *_Name )
    {
    	for( int i = NULL; i <= GetFirstVar( ); i++ )
    	{
    		if( !strcmpi( gVar[ i ].Name, _Name ) ) return i;
    	}
    	return -1;
    }
    
    void cVars::SetFirstVar( int _Value )
    {
    	this->iGetFirstVar = _Value;
    }
    
    string cVars::GetCurDir( )
    {
    	char	chTemp[ 256 ];
    	string	szTemp;
    	GetCurrentDirectory( 256, chTemp );
    	szTemp = chTemp;
    	return szTemp;
    }
    
    float cVars::GetPrivateProfileFloat( LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpFilePath )
    {
    	char	chTemp[ 256 ];
    	float	flTemp;
    	GetPrivateProfileString( lpAppName, lpKeyName, NULL, chTemp, 256, lpFilePath );
    	flTemp = atof( chTemp );
    	return flTemp;
    }
    void cVars::StartUp( )
    {
    	this->iGetFirstVar = NULL;
    }
    
    void cVars::AddVar( char *_Name, float _flValue, float _flMinValue, float _flMaxValue, string _AppName, string _KeyName, string _Filepath )
    {
    	int		iVar;
    
    	iVar = GetFirstVar( );
    
    	gVar[ iVar ].Name		=	_Name;
    	gVar[ iVar ].flValue	=	_flValue;
    	gVar[ iVar ].flMinValue	=	_flMinValue;
    	gVar[ iVar ].flMaxValue	=	_flMaxValue;
    	gVar[ iVar ].AppName	=	_AppName;
    	gVar[ iVar ].KeyName	=	_KeyName;
    	gVar[ iVar ].Filepath	=	 this->GetCurDir( );
    	gVar[ iVar ].Filepath	+=	_Filepath;
    
    	gVar[ iVar ].flValue	=	this->GetPrivateProfileFloat( _AppName.c_str( ), _KeyName.c_str( ), gVar[ iVar ].Filepath.c_str( ) );
    
    	if( gVar[ iVar ].flValue > gVar[ iVar ].flMaxValue )
    	{
    		gVar[ iVar ].flValue = gVar[ iVar ] .flMaxValue;
    	}
    	else if( gVar[ iVar ].flValue < gVar[ iVar ].flMinValue )
    	{
    		gVar[ iVar ].flValue = gVar[ iVar ].flMinValue;
    	}
    
    	SetFirstVar( GetFirstVar( ) + 1 );
    }
    
    float cVars::GetValue( char *_Name )
    {
    	int		iVar;
    
    	iVar	= GetVarEntry( _Name );
    
    	if( iVar != -1 )
    	{
    		return gVar[ iVar ].flValue;
    	}
    	else
    	{
    		return 1337;
    	}
    }
    

    So. Ich will die String Variable AppName aus dem Struct und aus der AddVar funktion herausnehmen. Es soll später alles via KeyName gefunden werden. Das heißt meine Settings.ini Datei soll später so aussehen:

    overlay_interval 1.00
    overlay_active 1.00
    

    Dazu müsste ich die GetPrivateProfileFloat( LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpFilePath ) zu GetPrivateProfileFloat( LPCSTR lpKeyName, LPCSTR lpFilePath ) ändern. Meine Idee war es nun via fstream es zu lesen.

    float cVars::GetPrivateProfileFloat( LPCSTR lpKeyName, LPCSTR lpFilePath )
    {
    	float		flTemp;
    	ifstream	ifStream;
    
    	ifStream.open( lpFilePath );
    	// Fehlende Argumente um nach einem Leerzeichen in der Zeile zu suchen
    	// und dahinter den Float Wert in flTemp zu zuweisen
    	//
    
    	return flTemp;
    }
    

    Hat eventuell jemand Davon ahnung? :s Ich bin einwenig am verzweifeln..
    Grüße



  • ifstream    ifStream; 
        ifStream.open( lpFilePath ); 
        //
    

    Wie war das nochmal, SeppJ? 37 Menschen in China sterben, weil ein Reissack auf sie fällt? 😃 😃
    Ach nein, das war

    SeppJ schrieb:

    Jedes Mal, wenn du eine Variable deklarierst und in der Zeile danach explizit initialisierst, anstatt gleich den passenden Konstruktor zu nehmen, weiß deine Oma, dass du sie nicht mehr lieb hast.

    Aber wegen:

    Jedes Mal, wenn du eine Zählschleife als while-Schleife schreibst, wird die Welt ein bisschen schlechter.

    Das ist nun mal wirklich Geschmackssache. Ich tendiere zwar zur for-Schleife, aber es ist einfach nicht schlimm da while zu benutzen, nur weil die Konvention es anders vorschreibt.


  • Mod

    Wow! Da hast du aber tief im Forum gegraben, um das Zitat wieder zu finden. 👍

    Ich hätte ja über ganz andere Designentscheidungen (globales, dynamisch allokiertes Objekt!) gelästert, aber da ich zugegebenermaßen gerade etwas betrunken bin, überlasse ich das mal lieber anderen.



  • Sone schrieb:

    ifstream    ifStream; 
        ifStream.open( lpFilePath ); 
        //
    

    Wie war das nochmal, SeppJ? 37 Menschen in China sterben, weil ein Reissack auf sie fällt? 😃 😃
    Ach nein, das war

    SeppJ schrieb:

    Jedes Mal, wenn du eine Variable deklarierst und in der Zeile danach explizit initialisierst, anstatt gleich den passenden Konstruktor zu nehmen, weiß deine Oma, dass du sie nicht mehr lieb hast.

    Aber wegen:

    Jedes Mal, wenn du eine Zählschleife als while-Schleife schreibst, wird die Welt ein bisschen schlechter.

    Das ist nun mal wirklich Geschmackssache. Ich tendiere zwar zur for-Schleife, aber es ist einfach nicht schlimm da while zu benutzen, nur weil die Konvention es anders vorschreibt.

    Das dafür eine For-Schleife passend ist ,ist mir schon bewusst nur die Parameter..



  • ungetestet:

    float cVars::GetPrivateProfileFloat( LPCSTR lpKeyName, LPCSTR lpFilePath )
    {
      float flTemp;
      std::string key
      for( std::ifstream ifStream(lpFilePath); ifStream >> key >> flTemp; )
      {
        if ( key == std::string(lpKeyName) ) return flTemp;
      }
    
      // Hier Fehlerbehandlung. Entweder Fehler beim lesen oder lpKeyName nicht gefunden
    }
    


  • Hallo 0x14D4,

    vielleicht sind einige der Informationen in diesem Thread für Dich hilfreich. Inklusive des Links auf 'Werte aus einer Config-Datei holen'.

    Gruß
    Werner


Anmelden zum Antworten