# Probleme beim Einlesen einer INI-Datei



## dtt (17. April 2004)

Liebe Forum-Community,

ich möchte mit VC++ 6 eine selbsterstelle INI-Datei einlesen und im weiteren Programmverlauf
auf die gespeicherten Werte zugreifen. Wie kann ich das am Einfachsten realisieren?

Die INI soll folgendes Format haben:
[abschnitt1]
variable1=wert1;
variable2=wert2;
...

Ich habe bereits mehrere Methoden versucht, aber mir gelingt es nicht, den Wert von der Variable zu trennen (bin noch Anfänger).  

Kann mir hier jemand weiterhelfen und hat vielleicht sogar jemand ein Code-Beispiel für mich?
Wäre klasse...


----------



## Kachelator (17. April 2004)

Ein Codebeispiel kann ich dir bei Gelegenheit raussuchen, aber es ist einfach, wenn du GetPrivateProfileString(), GetPrivateProfileInt() und so weiter verwendest. Die sind in der MSDN Lib gut dokumentiert.  Doku online


----------



## dtt (17. April 2004)

Das klingt schon mal vielversprechend, danke 

Wenn du noch ein Code-Beispiel findet, wäre es super, wenn du es posten könntest...


----------



## Kachelator (17. April 2004)

Eigentlich ist es wirklich sehr einfach, aber das Schreiben von Zahlen ist etwas nerviger, deshalb hier ein Beispiel, wo einfach nur ein int gelesen und sofort wieder gespeichert wird: 

```
#define DEFAULTVALUE_MATCHES (4711)
 
// Einlesen (hier mit int)
int iMatches = GetPrivateProfileInt( "Verschiedenes", "Matches", DEFAULTVALUE_MATCHES, "MeineIni.ini" );

// Schreiben
char szTemp[80];
wsprintf( szTemp, "%d", iMatches );
WritePrivateProfileString( "Verschiedenes", "Matches", szTemp, "MeineIni.ini" );

// Code ungetestet!
```
Übrigens dürfen ini-Dateien nur 32K gross werden, wenn man die PrivateProfile-Funktionen verwendet.


----------



## dtt (1. Mai 2004)

Habe nun folgende INI:

[section]
keyA=1


und folgenden Code:

#define DEFAULTVALUE_MATCHES (4711)

	int iMatches = GetPrivateProfileInt( "section", "keyA",
		DEFAULTVALUE_MATCHES, "meine.ini" );

	printf("%d gefunden!\n", iMatches);
	getch();


ich bekomme aber immer 4711 ausgegeben und nicht die 1.
was mach ich falsch?


----------



## Kachelator (2. Mai 2004)

Ich vermute, dass die Datei nicht gefunden wird. Gib mal den absoluten Pfad an.

Sonst entdecke ich keine Probleme.


----------



## dtt (2. Mai 2004)

Daran lags, vielen Dank!

Gibt es auch einen Trick, dass ich keinen absoluten Pfad angeben muss?


----------



## Kachelator (2. Mai 2004)

Nicht wirklich. Man kann zwar mit SetCurrentDirectory() arbeiten, aber es ist immer sicherer, einen absoluten Pfad zusammenzubauen.  Du könntest zum Beispiel GetModuleFileName() verwenden, um den Pfad der Exe herauszubekommen, und dann deinen relativen Pfad anhängen. Also gibt es doch eine Möglichkeit...  ach, hör nicht zu, ich bin zu vollgefressen, um vernünftig zu schreiben...


----------



## dtt (2. Mai 2004)

lol, ok, hat grad auf die Schnelle auch nicht so wirklich geklappt. Aber ich kann das doch über #define constant definieren oder nicht?
Wie müsste das aussehen?
#define ini = "\\meine.ini" tut nicht so wirklich

ok läuft *g*
const char* ini = "meine.ini"

vielen dank für deine hilfe


----------



## Endurion (2. Mai 2004)

Sämtliche Profile-Befehle funktionieren NUR mit absoluten Pfaden. Nicht absolute Pfade werden als im Windows-Verzeichnis liegend betrachtet, und das ist vermutlich nicht der Sinn der Sache.

GetModuleFileName ist schon ganz richtig, man muss nur den EXE-Dateinamen entfernen und dann den relativen Pfad anhängen.

Wenn ein Pfad absolut ist,  ist damit nicht const gemeint, sondern dass der Pfad komplett ist, also z. Bsp: Laufwerk:/Dir1/Dir2/usw... heisst.


----------



## Kachelator (2. Mai 2004)

> Sämtliche Profile-Befehle funktionieren NUR mit absoluten Pfaden. Nicht absolute Pfade werden als im Windows-Verzeichnis liegend betrachtet, und das ist vermutlich nicht der Sinn der Sache.


  Einspruch! Aus eigener Erfahrung weiss ich, dass zumindest die PrivateProfile-Befehle zunächst im aktuellen Verzeichnis suchen. Mag sein, dass sie auch noch im Windowsverzeichnis nachschauen, wie es in der MSDN Lib steht. 

Jedenfalls sollten absolute Pfade bevorzugt werden!


----------



## TaSy (2. Mai 2004)

*Gleiches Problem*

Ich hab etwa das gleiche Problem, wollte eine Klasse erstellen in der in ein INI Datei geschrieben werden kann und gleichzeitig auch ausgelesen werden kann. Nun habe ich das Problem wie gebe ich den Wert an das HauptProgie zurück? Und wie rufe ich es auf im Hauptprogramm! Schreiben klappt wunderbar!

Hier der Code:
void CInI::schreiben()
{
	WritePrivateProfileString("moon", "room", "Baschich", "c:\\temp\\Tool.ini");
	return;
}

char CInI::lesen()
{
	char temp[99];
	GetPrivateProfileSection("GENERAL", temp, sizeof(temp), "c:\\temp\\Tool.ini");


	return ?;

}

// im Hauptprog aufruf
?


----------



## Kachelator (3. Mai 2004)

```
char CInI::lesen()
{
char temp[99];
GetPrivateProfileSection("GENERAL", temp, sizeof(temp), "c:\\temp\\Tool.ini");


return ?;

}
```

Das sollte besser so aussehen (die Kommentare kannst du weglassen):
	
	
	



```
#include <string>

// ...

std::string lesen()
{
  char temp[99];
  
  //DWORD GetPrivateProfileString(
  //  LPCTSTR lpAppName,        // points to section name
  //  LPCTSTR lpKeyName,        // points to key name
  //  LPCTSTR lpDefault,        // points to default string
  //  LPTSTR lpReturnedString,  // points to destination buffer
  //  DWORD nSize,              // size of destination buffer
  //  LPCTSTR lpFileName        // points to initialization filename
  //);
  
  // du willst doch sicher den von dir
  // gespeicherten Wert zurücklesen, oder?
  GetPrivateProfileString(   "moon",   
                             "room", 
                             "default",
                             temp, 
                             99, 
                             "c:\\temp\\Tool.ini" );

  return std::string( temp );
}
```
Sieh dir bitte mal in der MSDN die Dokumentation an zu 
_GetPrivateProfileString()_ , _WritePrivateProfileString()_  und zu _std::basic_string._ 

Ausserdem empfehle ich ein gutes Buch über C++ für Einsteiger. Das würde die Hälfte deiner Probleme mit den Routinen lösen.


----------



## Kachelator (3. Mai 2004)

Ich hatte noch was vergessen:


----------



## boschba (18. Oktober 2004)

Hallo,

ich habe auch noch nicht viel Erfahrung in C++ und wollte mal dieses Beispiel ausprobieren aber ich weiß nicht was ich falsch gemacht habe, da er mir zurückgibt, er würde die Funktion "GetPrivateProfileString" nicht kennen!

hier mein Code

```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define DEFAULTVALUE_MATCHES (4711)


int main(void)
{

int iMatches = GetPrivateProfileInt( "smart", "hdd",DEFAULTVALUE_MATCHES, "smart.ini" );

printf("%d gefunden!\n", iMatches);
getch();

return 0;

}
```

Wäre super wenn mir jemand weiter helfen könnte.

Danke im Voraus.

gruß Michael


----------



## Radhad (18. Oktober 2004)

Du schreibst das in C, während oben der Code in C++ geschrieben ist. Das ist so direkt nicht kompatibel, da ihr verschiedene Bibliotheken benutzt. Ich weiß jetzt zwar nicht ob die Befehle, die kachelator genannt hat, in der iostream drinne stehen oder nicht, aber ganz bestimmt nicht in der stdio ;-)


MfG Radhad


----------



## boschba (18. Oktober 2004)

hi,

ich habe jetzt noch die windows.h hinzugefügt, jetzt kompiliert er mir das prog,
aber er gibt mir immer nur den wert 4711 aus!
Auch wenn ich den Pfad absolut angebe.

Mein logfile sieht wie folgt aus:


```
[smart]

hdd=1
```


----------



## boschba (18. Oktober 2004)

danke für die hilfe

ich habe meinen Fehler selbst gefunden:
windows hat mal wieder die Endung txt an die ini datei angehängt

xxx.ini.txt

hätte ich auch ehr drauf kommen können.


----------



## JumpLink (7. Juli 2005)

Hi! Ich habe auch noch solch ein Problem, nur muss ich einen Kompletten Text in eine Variable schreiben, wie geht das?

       Meine ini:


```
[HM_MP]
  Title=Testspiel
  Mode=0
  Zoom=0
```
 "Testspiel" ist das entscheidende Wort.


----------



## JumpLink (9. Juli 2005)

Hi ich habe nun folgendes neues Problem, nachdem meine Frage wohl leider nicht beantwortet werden konnte habe ich weiter selbst versucht einen weg zu finden. Ich habe gerade eine gute Idee im Kopf mit der ich das umsetzen kann und bin gerade dabei die Idee in einen Quelltext umzuwandeln. 





   Naja, ich bin so weit gekommen:




```
#include <stdio.h>

   #include <stdlib.h>

   #include <iostream.h>

   #include <string.h>

    

   void main(void)

   {

    

   			FILE *datei;

   			char bezeichnung[9];	//9 ist die Anzahl der Ziffern (- 1 wegen beginn ab 0) der Bezeichnung

   			strcpy(bezeichnung,"GameTitle=");

   			char fensterueberschrift[40], temp[4000];

   			int anz, a;

    

   			if((datei = fopen("HM_MP.ini","r")) == NULL)

   			{

   					    cout << "Fehler beim Oeffnen der Datei: RPG_RT.ini";

   					    exit(1);

   			}

    

   			anz = fread(temp,sizeof(char),4000,datei);

   			temp[anz]=NULL;

   			cout << temp;

    

   			fclose(datei);

   }
```



   Als ich dann weitergemacht habe kam das dabei heraus:




```
#include <stdio.h>

   #include <stdlib.h>

   #include <iostream.h>

   #include <string.h>

    

   void main(void)

   {

    

   			FILE *datei;

   			char bezeichnung[9];	//9 ist die Anzahl der Ziffern (- 1 wegen beginn ab 0) der Bezeichnung

   			strcpy(bezeichnung,"GameTitle=");

   			char fensterueberschrift[40], temp[4000];

   			int anz, a;

    

   			if((datei = fopen("HM_MP.ini","r")) == NULL)

   			{

   					    cout << "Fehler beim Oeffnen der Datei: RPG_RT.ini";

   					    exit(1);

   			}

    

   			anz = fread(temp,sizeof(char),4000,datei);

   			temp[anz]=NULL;

   			cout << temp;

    

   			for(a=0; a=anz-9; a++)

   			{

   					    if(temp[a]==bezeichnung[0] &&

   					       temp[a+1]==bezeichnung[1] &&

   					       temp[a+2]==bezeichnung[2] &&

   					       temp[a+3]==bezeichnung[3] &&

   					       temp[a+4]==bezeichnung[4] &&

   					       temp[a+5]==bezeichnung[5] &&

   					       temp[a+6]==bezeichnung[6] &&

   					       temp[a+7]==bezeichnung[7] &&

   					       temp[a+8]==bezeichnung[8] &&

   					       temp[a+9]==bezeichnung[9])

   					    {

   								   break;

   					    }					  

   			}

   			a=a+9;

   			cout << a;

   			fclose(datei);

   }
```







   Ich habe also nur das hier dazugefügt:




```
for(a=0; a=anz-9; a++)

   			{

   					    if(temp[a]==bezeichnung[0] &&

   					       temp[a+1]==bezeichnung[1] &&

   					       temp[a+2]==bezeichnung[2] &&

   					       temp[a+3]==bezeichnung[3] &&

   					       temp[a+4]==bezeichnung[4] &&

   					       temp[a+5]==bezeichnung[5] &&

   					       temp[a+6]==bezeichnung[6] &&

   					       temp[a+7]==bezeichnung[7] &&

   					       temp[a+8]==bezeichnung[8] &&

   					       temp[a+9]==bezeichnung[9])

   					    {

   								   break;

   					    }					  

   			}

   			a=a+9;
```





   doch plötzlich zeigt mir das Programm keinen Text mehr an, vorher aber wurde mir der Inhalt der ini Datei angezeigt, hat jemand eine Ahnung warum?



   Falts sich jemand fragt was das Programm bringt, noch bringt es nichts, da es noch nicht fertig ist.


----------



## dtt (9. Juli 2005)

hi jumplink,

also ich hab da auf die schnelle mal 2 Fehler entdeckt.

Ich habe das so verstanden, dass die Variable bezeichnung 10 Zeichen speichern soll.
dann musst du sie aber so deklarieren:
char bezeichnung[10]; // 10 Felder, abzufragen über 0-9

zum 2. ist ein Fehler in der for-Bedingung: for(a=0; a=anz-9; a++)
da hast du wohl ein '=' vergessen.
Probier mal: for( a = 0; a == anz-9; a++ )
denn '=' ist nur eine Wertzuweisung, du brauchst aber ja einen Bedingung (< > == !=) für das Schleifenende.

hoffe ich konnte dir etwas weiterhelfen.


----------



## JumpLink (10. Juli 2005)

Ja danke, daran lag es. ^^


*Edit:*
  ne doch nicht, jetzt wird die Schleife übersprungen, hä?
  Ich benutze übrigents MSVisualC++6.

*Edit2:
*Ah, jetzt gehts, musste "for(a=0;a!=anz-10;a++)" heißen.


----------



## Hallasas (3. Mai 2007)

Leider ist dieser Thread schon sehr alt, aber ich gebe trotzdem noch eine Antwort, da ich Threads mit ungelösten problemen nicht abhaben kann.

```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
///////////////////////
#include <windows.h> // hier befindet sich die Syntax "GetPrivateProfileInt"
///////////////////////

#define DEFAULTVALUE_MATCHES (4711)


int main(void)
{

int iMatches = GetPrivateProfileInt( "smart", "hdd",DEFAULTVALUE_MATCHES, "smart.ini" );
// hier konnte ich die antwort "4711 gefunden!" mit "./ini/smart.ini" lösen

printf("%d gefunden!\n", iMatches);
getch();

return 0;

}
```

Ich hoffe, ich konnte helfen.

// edit
huch, die anderen posts wurden nicht angezeigt...


----------

