Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
#include <string> #include <iostream> #include <fstream> #include <iterator> class IniReader{ public: static int getIntager( std::string path, std::string Category, std::string keyword, int defvalue){ std::fstream stream(path, std::ios_base::in); // File öffnen stream << std::noskipws; // Keine Enter überspringen if(stream.bad()) throw std::runtime_error("Error when opening file: " + path + "."); // Wenn die Datei nicht vorhanden oder beschädigt ist: error std::istream_iterator<char> begin(stream), end_of_file; // // Datei Inhalt in einen String packen std::string buffer(begin, end_of_file); // stream.close(); size_t categoryPos1 = buffer.find( "[" + Category + "]" ); // Position vom Tag rausfinden size_t categoryPos2 = buffer.find( "[/" + Category + "]" ); // Position vom Closing Tag rausfinden size_t len = categoryPos2 - categoryPos1; // Länge zwischen Tag und Closing Tag rausfinden std::string subCategory = buffer.substr( categoryPos1, len ); // Einen Substring anlegen da kommt alles rein was zwischen dem Tag und dem Closing Tag steht! size_t keywordPos = 0; // Die position des keywords if( ( keywordPos = subCategory.find( keyword ) ) != std::string::npos ){ // keyword finden std::string value = subCategory.substr( keywordPos - 1 ); // davon einen neuen string erstellen ( Nur die Zeile in der das keyword drin steht ist jetzt in value vorhanden ) size_t valuepos = value.find( "=" ); // Nur den Wert hinter dem '=' rausfinden std::string THEVALUE = value.substr( valuepos + 1); // Den wert in THEVALUE schreiben int toInt = atoi( THEVALUE.c_str() ); // umwandeln return toInt; // zurückgeben } return defvalue; // Wenn das obere nicht funktioniert hat wird ein defaultwert zurück gegeben welchen man selber aussuchen darf } static std::string getString( std::string path, std::string Category, std::string keyword, std::string defvalue){ std::fstream stream(path, std::ios_base::in); stream << std::noskipws; if(stream.bad()) throw std::runtime_error("Error when opening file: " + path + "."); std::istream_iterator<char> begin(stream), end_of_file; std::string buffer(begin, end_of_file); stream.close(); size_t categoryPos1 = buffer.find( "[" + Category + "]" ); size_t categoryPos2 = buffer.find( "[/" + Category + "]" ); size_t len = categoryPos2 - categoryPos1; std::string subCategory = buffer.substr( categoryPos1, len ); size_t keywordPos = 0; if( ( keywordPos = subCategory.find( keyword ) ) != std::string::npos ){ std::string value = subCategory.substr( keywordPos - 1 ); size_t valuepos = value.find( "=" ); std::string THEVALUE = value.substr( valuepos + 1); return THEVALUE; } return defvalue; } static bool getBool( std::string path, std::string Category, std::string keyword, bool defvalue){ std::fstream stream(path, std::ios_base::in); stream << std::noskipws; if(stream.bad()) throw std::runtime_error("Error when opening file: " + path + "."); std::istream_iterator<char> begin(stream), end_of_file; std::string buffer(begin, end_of_file); stream.close(); size_t categoryPos1 = buffer.find( "[" + Category + "]" ); size_t categoryPos2 = buffer.find( "[/" + Category + "]" ); size_t len = categoryPos2 - categoryPos1; std::string subCategory = buffer.substr( categoryPos1, len ); size_t keywordPos = 0; if( ( keywordPos = subCategory.find( keyword ) ) != std::string::npos ){ std::string value = subCategory.substr( keywordPos - 1 ); size_t valuepos = value.find( "=" ); std::string THEVALUE = value.substr( valuepos + 1); int toInt = atoi( THEVALUE.c_str() ); bool Result = 0; if( toInt < 0 || toInt > 1 ) return defvalue; else Result = toInt; return Result; } return defvalue; } }; |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Fawkes« (19.06.2013, 21:42)
Zitat
Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.
Warum dann nicht gleich xml?
<bla></bla>
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
template<typename _Ty> static _Ty get(const std::string& path, const std::string& Category, const std::string& keyword, const _Ty& defvalue) { std::string value = getString(path, Category, keyword); // erst holen wir uns den einen string mit dem int oder bool oder so std::istringstream iss(value); _Ty extr; // <- hier wird hinextrahiert iss >> extr; // <- extrahiere if(!iss.fail()) // <- prüfe ob ein fehler aufgetreten ist return extr; else return defvalue; } ... // Benutze es mit: int window_width = IniReader::get("config.ini", "graphics", "width", 800); |
Ich bevorzuge meistens auch ini Dateien.
Sie haben, verglichen mit XML Dateien, wesentlich weniger overhead und sind daher auch schneller und vor allem leichter zu parsen.
Hmm, wenn es funktioniert ist es doch ok
Allerdings frage ich mich wieso getInteger und getBool nicht auf getString aufbauen... du öffnest und "parsed" die datei jetzt in jeder der drei funktionen... dabei ist der einzige unterschied, dass sie den string den sie extrahieren unterschiedlich behandeln...
Das problem mit dem closing-tag könntest du lösen indem du mit std::getline einfach jede zeile durchgehst und erst nach dem tag suchst ([...]) und dann nach dem key (... = ....).
Ganz abgesehen davon, sollte es in deinem code zu fehlern kommen, wenn das format eben falsch ist (kein closing-zag existiert)!!!
Weiterhin, brauchst du gar nicht substr benutzen, denn du kannst dem find einen iterator übergeben, ab dem er dann anfängt zu suchen.
Schön wäre es natürlich auch, wenn du beim konvertieren anstatt atoi und so, std:istringstream verwendest. Dann kannst du auch in alle möglichen typen konvertieren. das sehe dann mit einer getString methode so aus:
C-/C++-Quelltext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 template static _Ty get(const std::string& path, const std::string& Category, const std::string& keyword, const _Ty& defvalue) { std::string value = getString(path, Category, keyword); // erst holen wir uns den einen string mit dem int oder bool oder so std::istringstream iss(value); _Ty extr; // <- hier wird hinextrahiert iss >> extr; // <- extrahiere if(!iss.fail()) // <- prüfe ob ein fehler aufgetreten ist return extr; else return defvalue; } ... // Benutze es mit: int window_width = IniReader::get("config.ini", "graphics", "width", 800);
Die Methode ist gut ich überarbeite das eben.
Edit: Oder auch nicht hehe, ich weiß leider nicht wie ich das überarbeiten soll. Aber wenn jemand hier den Code überarbeiten will, gerne. Mir geht es sowieso nur darum, dass man in google mal etwas aktuelles zum Thema Inireader findet. Als ich einen brauchte habe ich lange gesucht aber nichts gefunden. Zumindest nichts Plattformunabhängiges und akutuelles.
Ich bevorzuge meistens auch ini Dateien.
Sie haben, verglichen mit XML Dateien, wesentlich weniger overhead und sind daher auch schneller und vor allem leichter zu parsen.
Benutze rapidxml und dann kannst du Geschwindigkeitsvorteile vergessen... rapidxml ist so gut optimiert, das selbst ein inireader nur vernachlässigbar schneller sein wird (wenn überhaupt),
denn ini datein sind meistens so wie so nicht so groß...
C-/C++-Quelltext |
|
1 2 3 4 |
int main(int _argc, char** _argv) noexcept { asm volatile("lock cmpxchg8b %eax"); return 0; } // ::main |
XML D: Oh, Gott, dieses mit nutzlosen Zeichen vollgestopfte Format. Boost bietet mit seinem "property_tree" die Möglichkeit, Daten als Baumstruktur zu (de-)serialisieren und unterstützt dabei auch die Formate XML, JSON, INI, und "Info", wobei "Info" ein minimalistischer Selbstbau ist, der syntaktisch JSON/YAML ähnelt.
Werbeanzeige