Schlüssel aus Ini-Datei lesen - noch eine Frage zu eof();



  • D.h. das zeilenweise Auslesen ist tatsächlich dem Buchstabenweisen vorzuziehen?
    Mir erschien das eher umständlich, da ich dann Auslesen und Auswerten getrennt behandeln müsste...

    @SeppJ:
    Bis gerade eben wusste ich nicht, wonach genau ich bei Google für ">>" suchen muss (auf "Doppelpfeil" bin ich vor fünf Minuten gekommen. 🙄 )... aber okay, trotzdem danke für den Tipp. 😉



  • Frenni schrieb:

    D.h. das zeilenweise Auslesen ist tatsächlich dem Buchstabenweisen vorzuziehen?
    Mir erschien das eher umständlich, da ich dann Auslesen und Auswerten getrennt behandeln müsste...

    Du musst nicht trennen. Du kannst die strings in einem vector speichern oder die strings auch direkt auswerten.



  • Verstehe ich das richtig: man kann eine mit getline() "erhaltene" Zeile nach einzelnen Zeichen durchsuchen, ohne sie vorher in Strings zu speichern?



  • Frenni schrieb:

    Verstehe ich das richtig: man kann eine mit getline() "erhaltene" Zeile nach einzelnen Zeichen durchsuchen, ohne sie vorher in Strings zu speichern?

    Du kannst getline() mit dem dritten Argument sagen, bis wohin er lesen soll.

    "Key1" = ...
    "Key2" = ...
    
    // Wenn "-Zeichen immer am Anfang :
    cin.get();
    std::string key = "";
    getline(cin, key, "\"");
    
    // "-Zeichen irgendwo mittendrin:
    cin.ignore(numerlic_limits<streamsize>::max(), "\"");
    getline(cin, key, "\"");
    


  • Dankeschön! 🙂

    Ich werd auf jeden Fall darauf zurückgreifen, wenn ich etwas bewanderter in der ganzen Syntax von C++ bin. Aber jetzt les ich erstmal einen Crashkurs und hau nächstes Semester unsere Profs, dass sie mal früher mit C++ anfangen sollen. 😃

    Danke für die schnellen Antworten!



  • So, hoffe ich darf nochmal nerven...

    Ich bin jetzt ein ganzes Stück weiter gekommen (auch wenn es vielleicht nicht die professionellste Lösung ist, funktioniert's und getline() ist drin... ^^).

    Allerdings habe ich jetzt noch ein Problem mit ios::eof.
    Mein Code sieht folgendermaßen aus:

    ifstream File;
    		File.open("...Pfad...", ios::nocreate);
    
    		if(File){
    			int lc, ch, doline;
    			String strKey = "";
    			char arKey[100];
    
    			for(lc=1;;lc++){ //lc=line Counter für Fehlermeldung
    
    				File.getline(arKey, 100);
    				if(File.eof()){break;} 
    
    				switch(arKey[0]){
    					case '[': 
    					case ' ':
    						doline = 0;
    						break;
    					case '"':    //nur best. Zeilen sollen beachtet werden
    						doline = 1;
    						break;
    					default:
    						doline = 0;
    						//...Fehlermeldung...
    						break;
    				}
    
    				if(!doline){continue;}
    
    				for(ch=1;ch<100;ch++){
    					if((arKey[ch] == '"')||(arKey[ch] == '=')||(arKey[ch] == '\n')){break;}
    					strKey = strKey + arKey[ch];
    				}
    				//...Ausgabe des Strings...
    				File.close();
    			}
    		}
    

    Funktioniert grundsätzlich ganz gut, nur leider hört das Auslesen nach der ersten Zeile, die ein " enthält, auf.
    Anscheinend wird File.eof() in Zeile 12 "true" und bricht die Schleife ab.

    Aber warum? Sollte das nicht erst passieren, nachdem wirklich das Ende der Datei erreicht wurde?

    Grüße,
    GoldenAge





  • Und falls es dir nach wie vor erstmal nur um dieses geht:

    Frenni schrieb:

    [...]in jeder Zeile das erste Wort zwischen zwei Anführungszeichen in einem String oder Array speichern.[...]

    Dann kann dir vielleicht dieses kurze Stückchen Code als Anregung dienen:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <algorithm> // std::copy
    #include <iterator>  // std::ostream_iterator
    
    int main()
    {
    	std::ifstream fileIn("test.txt");
    	if(!fileIn) {
    		std::cerr << "Datei wurde nicht gefunden." << std::endl;
    		return 1;
    	}
    	std::vector<std::string> gefundeneWoerter;
    	for(std::string zeile; std::getline(fileIn, zeile); ) { // Zeile für Zeile lesen
    		std::string::size_type pos1 = zeile.find('\"');		   // Die ersten beiden
    		std::string::size_type pos2 = zeile.find('\"', pos1 + 1); // Anführungszeichen finden
    		while(pos1 != std::string::npos && pos2 != std::string::npos) {
    			gefundeneWoerter.push_back(zeile.substr(pos1 + 1, pos2 - pos1 - 1)); // std::string bilden ab (pos1 + 1)ter Position aus (pos2 - pos1 - 1) Zeichen
    			pos1 = zeile.find('\"', pos2 + 1);	// Nach weiteren
    			pos2 = zeile.find('\"', pos1 + 1);	// Anführungszeichen suchen
    		}
    	}
    	std::copy(gefundeneWoerter.begin(), gefundeneWoerter.end(), std::ostream_iterator<std::string>(std::cout, "\n")); // Ausgabe
    
    	return 0;
    }
    


  • @Varginator:
    Ich kann leider nicht sagen, ob diese Klasse auch die Keys auslesen kann, aber Ini-Dateien grundsätzlich auszulesen habe ich schon geschafft. 🙂

    @Mizar:
    Well... naja, das ist dann wohl die elegante Lösung. 😃
    Nur hätte ich wohl zwei Wochen gebraucht, um mir die ganzen Funktionen zusammenzusuchen, also erstmal Danke!

    for(std::string zeile; std::getline(fileIn, zeile); ) { // Zeile für Zeile lesen
    		std::string::size_type pos1 = zeile.find('\"');		   // Die ersten beiden
    		std::string::size_type pos2 = zeile.find('\"', pos1 + 1); // Anführungszeichen finden
    		while(pos1 != std::string::npos && pos2 != std::string::npos) {
    			gefundeneWoerter.push_back(zeile.substr(pos1 + 1, pos2 - pos1 - 1)); // std::string bilden ab (pos1 + 1)ter Position aus (pos2 - pos1 - 1) Zeichen
    			pos1 = zeile.find('\"', pos2 + 1);	// Nach weiteren
    			pos2 = zeile.find('\"', pos1 + 1);	// Anführungszeichen suchen
    		}
    	}
    

    Allerdings verstehe ich diese For-Schleife noch nicht ganz ... wird sie einfach abgebrochen, wenn getline eine 0 zurückgibt? Kann es nicht sein, dass eine Datei mitten in der Zeile aufhört und so Daten verloren gehen?

    Edit: Und die Zeilen 6 + 7 suchen nach weiteren Anführungszeichen in derselben ausgelesenen Zeile, oder?

    Abgesehen davon funktioniert std::getline(fileIn, zeile); bei mir leider nicht (BDS 2006 kennt die Funktion nicht) - was mich einiges an Zeit und Nerven gekostet hat, da ich ständig dachte, ich hätte sie irgendwie falsch verwendet. 😞
    Daher meine etwas umständlichere Variante mit dem Array - oder kann man das irgendwie nachinstallieren?



  • Frenni schrieb:

    Allerdings verstehe ich diese For-Schleife noch nicht ganz ... wird sie einfach abgebrochen, wenn getline eine 0 zurückgibt? Kann es nicht sein, dass eine Datei mitten in der Zeile aufhört und so Daten verloren gehen?

    Der allgemeine Aufbau einer for-Schleife lautet ja:

    for(Initialisierer; Bedingung; Ausdruck)
        Anweisung;
    

    In der for-Schleife meines Codestücks habe ich als Bedingung folgendes verwendet:

    std::getline(fileIn, zeile)
    

    Die std::getline -Funktion hat als Rückgabewert den ihr übergebenem Stream und eben dieser wird nun in der "Bedingung" der for-Schleife ausgewertet. Es wird also einfach überprüft, ob sich der Stream in einem gültigen Zustand befindet.

    Frenni schrieb:

    Edit: Und die Zeilen 6 + 7 suchen nach weiteren Anführungszeichen in derselben ausgelesenen Zeile, oder?

    Ganz genau. Und wird die while-Schleife wieder verlassen, liest die for-Schleife die nächste Zeile aus der Datei und diese wird nun (dank der while-Schleife) solange nach Anführungszeichen durchsucht, bis eben keine mehr gefunden werden. Usw., usf... 🙂

    Frenni schrieb:

    Abgesehen davon funktioniert std::getline(fileIn, zeile); bei mir leider nicht (BDS 2006 kennt die Funktion nicht) - was mich einiges an Zeit und Nerven gekostet hat, da ich ständig dachte, ich hätte sie irgendwie falsch verwendet. 😞
    Daher meine etwas umständlichere Variante mit dem Array - oder kann man das irgendwie nachinstallieren?

    Hmm... ich verwende als IDE Microsofts Visual Studio 2008 Express Edition und durch einfaches einbinden des std::string -Headers:

    #include <string>
    

    kann ich die std::getline -Funktion schon verwenden. Leider kann ich dir nicht sagen wie es sich da mit dem BSD 2006 verhält.



  • Mizar schrieb:

    Frenni schrieb:

    Edit: Und die Zeilen 6 + 7 suchen nach weiteren Anführungszeichen in derselben ausgelesenen Zeile, oder?

    Ganz genau. Und wird die while-Schleife wieder verlassen, liest die for-Schleife die nächste Zeile aus der Datei und diese wird nun (dank der while-Schleife) solange nach Anführungszeichen durchsucht, bis eben keine mehr gefunden werden. Usw., usf... 🙂

    Okay... die zwei Zeilen braucht es in dem Fall nicht, ich such immer nur das erste Wort zwischen zwei "", der Rest ist mir egal. 🙂

    Zum Rest:
    Jetzt hänge ich also doch wieder an diesem blöden getline() fest... 🙄
    Obwohl: Kann ich die Variante mit Array (Reference) genauso benutzen? D.h. als Bedingung der for-Schleife File.getline(array, size) einsetzen?



  • Frenni schrieb:

    Obwohl: Kann ich die Variante mit Array (Reference) genauso benutzen? D.h. als Bedingung der for-Schleife File.getline(array, size) einsetzen?

    Als Bedingung der for-Schleife dürfte das schon funktionieren, ja. Was ich mich gerade frage ist, ob das BDS 2006 überhaupt die std::string s aus der C++-Standardbibliothek kennt. In deinem zuvor geposteten Code hattest du ja auch dieses geschrieben:

    String strKey = "";
    

    Was ja auch kein std::string ist (man achte auf das große 'S'). Falls das BDS 2006 keine std::string s aus der C++-Standardbibliothek unterstützt, wirst du dich entweder mit Arrays herumschlagen müssen oder schauen müssen was dir diese String-Klasse des BDS 2006 an Funktionalität bietet. Denn diese Anweisungen:

    std::string::size_type pos1 = zeile.find('\"');
    pos1 != std::string::npos
    zeile.substr(pos1 + 1, pos2 - pos1 - 1)
    

    dürften dann ja wohl nicht mehr funktionieren 😞



  • Das würde natürlich erklären, warum die Strings selten das tun, was ich von ihnen erwarte. 😃

    <string> habe ich durchaus eingebunden, leider kann ich dir nicht sagen, was da drin steht, oder welche Variante das ist.

    Hilft nur Probieren... immerhin hab ich mir jetzt mal ein Buch für den C++ Builder ausgeliehen, damit komme ich hoffentlich weiter.


Anmelden zum Antworten