[GELÖST] Probleme beim Einlesen/Ausgeben (fstream, Stringarray)
-
Morgen,
ich bastel mir gerade einen ganz simplen Parser, der aus einer Datei folgender Bauweise ein Stringarray erzeugt, das Variablenname und Variablenwert ausließt.
Var Wert Test Musterfield.h
#ifndef READ_CONFIG_H #define READ_CONFIG_H #include <fstream> #include <iostream> #include <string> class Files { // VARIABLEN std::string vars_[64][2]; // max. 64 lines, 2 states: varname and value const char* filename_; std::fstream file_; int items_; public: // GETTERS const char* getVar_(const char* var); // SETTERS void setVar_(const char* var, const char* value); // COSTRUCTORS Files(const char* filename, bool &proof); ~Files(); private: // FUNCTIONS void write_(); void add_(); }; #endifDer Konstruktor sieht hierbei folgendermaßen aus:
Files::Files(const char* filename, bool &proof) { // VARIABLES filename_ = new char[255]; filename_ = filename; items_ = 0; // index for loop char* c = new char[255]; bool b = 0; // index (varname or value?) file_.open(filename_,ios::in); // open file if ( file_.good() ) { cout << "Datei geladen: " << filename_ << endl; while ( ! file_.eof() ) { // Read and Save varname file_ >> c; if ( ! file_.eof() ) { vars_[items_][b] = c; if ( b == 0 ) { b = 1; } else { b = 0; items_++; } cout << vars_[items_][0] << ":" << vars_[items_][1] << endl; } } proof = true; } else { cout << "Could not open " << filename_ << "!" << endl; this->~Files(); proof = false; } file_.close(); }Lege ich nun ein Objekt an, dann wird mir an der Stelle von
cout << vars_[items_][0] << ":" << vars_[items_][1] << endl;folgendes ausgegeben:
Var:
:
test:
:Dennoch wird die Datei richtig geschrieben:
void Files::write_() { file_.open(filename_,ios::out); // open file for( int i = 0; i <= items_; i++ ) { file_ << vars_[i][0] << " " << vars_[i][1] << endl; } file_.close(); }(Die Funktion wird auch im Destruktor aufgerufen)
Ich weiß nicht mehr weiter und bitte um Hilfe.
-
} else { b = 0; items_++; } cout << vars_[items_][0] << ":" << vars_[items_][1] << endl;items_ ist jetzt schon auf dem nächsten Element.
-
manni66 schrieb:
items_ ist jetzt schon auf dem nächsten Element.
Autsch, das tut nur selbst weh.

Dann liegt das eigentliche Problem vorbeigeschossen und es liegt in der const char* File::getVar_()
const char* Files::getVar_(const char* var) { for ( int i; i < items_; i++ ) { if ( var == ( vars_[i][0].c_str() ) ) { return vars_[i][1].c_str(); } } return ""; }Wenn ich diese Funktion nämlich mit
Files config( CONFIGFILE, test ); // CODE (Überprüfung der bool test cout << config.getVar_("test") << endl;aufrufe, erhalte ich eine Leerzeile in der Ausgabe bzw. den String, der zurückgegeben werden soll, wenn keine Übereinstimmung gefunden wird, obwohl vars_[1][0] in diesem Fall "test" betragen müsste.
-
Schon schlimm, was manche als C++ bezeichnen. Hierfür würde ich einen std::ifstream nehmen und die Key-Value Paare in eine std::map<std::string, std::string> speichern. In etwa so (ungetestet):
class property_reader { std::map<std::string, std::string> properties; public: const std::string filename; property_reader(std::string filename) : filename(filename) { std::ifstream is(filename.c_str()); std::string line; while(std::getline(is, line)) { size_t i = line.find(' '); properties.insert(std::make_pair(line.substr(0, i), line.substr(i))); } } std::string get(const std::string& property) const { auto i = properties.find(property); if(i != properties.end) return i->second; throw not_found_error(property); } void set(std::string key, std::string value) { map.insert(std::make_pair(std::move(key), std::move(value)); } ~property_reader() { std::ofstream os(filename.c_str()); for(auto i = properties.begin(); i != properties.end(); ++i) os << i->first << ' ' << i->second << '\n'; } };
-
Daran hatte ich gar nicht gedacht. Ich werde es mal probieren, danke.
EDIT:
Was hat es mit den auto-Variablen auf sich?
Der Compiler gibt mir die Fehlermeldung aus, dass diese nicht ohne Dateityp deklariert werden können.
-
Ki schrieb:
Was hat es mit den auto-Variablen auf sich?
Der Compiler gibt mir die Fehlermeldung aus, dass diese nicht ohne Dateityp deklariert werden können.In C++03 bezeichnete es IM(H)O "RAII", deshalb brauchst du auch einen Datentyp. Im kommenden Standard bedeutet es die Ableitung des Datentyps durch seinen Initialisierungswert.
-
und welcher Datentyp muss das in diesem Fall sein?
Wenn ich die Variable mitstd::map<std::string,std::string>::iterator in;deklariere, wie heir (http://www.cplusplus.com/reference/stl/map/find/) beschrieben, dann gibt es haufenweise no-match-Fehlermeldungen.
-
Thema erledigt, Problem gelöst. Habe den Code nach einigen Schwierigkeiten folgendermaßen umgeschrieben und es funktioniert wunderbar:
reader.h
#ifndef READER_H #define READER_H #include <iostream> #include <string> #include <map> #include <fstream> class Reader { // VARIABLES std::map<std::string, std::string> items_; const std::string filename_; public: // CONSTRUCTORS Reader(std::string filename); ~Reader(); // GETTERS std::string get(const std::string& property) const; // SETTERS void set(std::string key, std::string value); // FUNCTIONS void write(); }; #endifreader.cpp
#include "reader.h" Reader::Reader(std::string filename) : filename_(filename) { std::ifstream is(filename_.c_str()); std::string line; while(std::getline(is, line)) { size_t i = line.find(' '); items_.insert(std::make_pair(line.substr(0, i), line.substr(i).erase(0,1))); } } std::string Reader::get(const std::string& item) const { std::map<std::string, std::string>::const_iterator in = items_.find(item); if(in != items_.end()) { return in->second; } return ""; } void Reader::set(std::string key, std::string value) { items_.insert(std::make_pair( key , value ) ); } void Reader::write() { std::ofstream os(filename_.c_str()); for( std::map<std::string, std::string>::iterator in = items_.begin(); in != items_.end(); ++in ) { os << in->first << ' ' << in->second << '\n'; } } Reader::~Reader() { write(); }EDIT:
Entschuldigung für den Doppelpost, ich dachte, man könne Beiträge löschen.