Zugriff von äußeren STL-liste auf innere STL-liste
-
Moinmoin,
ich habe folgendes Problem. Aus einer Datei muß verschieden lange Abschnittstexte und zudem
deren Abschittsbezeichnung lesen. Hierfür erstellte ich mir eine Struktur mit dem Aussehen:struct sSection { string SectionNumber; list<string> SectionText; };
Um jetzt eine Abschnittsbezeichnung und den Abschnitt zu lesen nutze ich folgenden Code:
typedef sSection *PSECTION; // Pointer auf eine Section-Struktur typedef std::list<string>::iterator TEXTITER; int main(void) { ifstream FileIn("Morgentau.txt"); if (FileIn) // Falls FileIn gültig ist. { PSECTION pSection=new sSection; string ReadString; getline(FileIn, ReadString); // einlesen der SectionNumber pSection->SectionNumber=ReadString; do // einlesen des SectionsText { // Trennzeichen zum nächsten // Datensatz [-] getline(FileIn, ReadString); if (ReadString != "[-]") pSection-> SectionText.push_back(ReadString); } while( ReadString != "[-]" ); // Ausgabe zu Testzwecken string ReadString2; for(TEXTITER iter= pSection->SectionText.begin(); iter!=pSection->SectionText.end();iter++) { ReadString2= *iter; cout << ReadString2 << '\n'; } } return 0; }
Das funktioniert bisher wunderbar um einen Abschnitt zu lesen.
Doch nun möchte ich, daß ich mehrere Abschnitte in eine Liste von sSection speichere.
Hierbei stößt bei mir das Problem auf, daß der binäre Operator = keinen Zugriff erlaubt.
Den Code, wie ich es mir dachte:struct sSection { string SectionNumber; list<string> SectionText; }; typedef sSection *PSECTION; // Pointer auf eine Section-Struktur typedef std::list<string>::iterator TEXTITER; typedef std::list<PSECTION> SECTIONLIST; typedef std::list<PSECTION>::iterator SECTIONLISTITER; /////////////////////////////////// // Hauptprogramm /////////////////////////////////// int main(void) { SECTIONLIST MainSectionList; ifstream FileIn("Morgentau.txt"); if (FileIn) // Falls FileIn gültig ist. { PSECTION pSection=new sSection; string ReadString; getline(FileIn, ReadString); // einlesen der SectionNumber pSection->SectionNumber=ReadString; do // einlesen des SectionsText { // Trennzeichen zum nächsten // Datensatz [-] getline(FileIn, ReadString); if (ReadString != "[-]") pSection-> SectionText.push_back(ReadString); } while( ReadString != "[-]" ); MainSectionList.push_back(pSection); SECTIONLIST pSectionList2; for(SECTIONLISTITER mainiter = MainSectionList.begin(); mainiter != MainSectionList.end(); mainiter++) { pSectionList2=*mainiter; for(TEXTITER iter= pSectionList2->SectionText.begin(); iter!=pSectionList2->SectionText.end();iter++) { ReadString= *iter; cout << ReadString << '\n'; } } } return 0; }
Muß ich den binären Operator überladen? Wenn ja, wie? Oder kann ich das Problem
auf eine andere einfachere Weise umgehen? Hinweise zum schöneren Codeaufbau
nehme ich gerne an. Das Proggen liegt bei mir mittlerweile ein Jahr zurückSönke
-
mal allgemein: zum durchiterieren würde ich for_each (o.ä.) nehmen. und diese typedefs (zum einen diese Großbuchstaben, die an die WinAPI erinnern, zum anderen aber auch dass du z.b. sSection* als PSECTION definierst) (meines erachtens) nicht wirklich guter stil. lass sie weg. wenn pointer dann schreib das auch hin, dass es einem sofort einleuchtet. ausserdem würd ich in der liste für die sections keine pointer sondern die strukturen als ganzes speichern, dann brauchst du dich nicht um das löschen des speichern kümmern, was im augenblick bei dir _nirgends_ passiwert. wenn du Zeiger in nen vektor/list/etc klatscht, dann werden auch nur diese gelöscht, und nicht der speicher freigegeben, auf den der zeiger zeigt.
bekommst du eine fehlermeldung? eigentlich müsste es nämlich so klappen denk ich (habs nicht ausprobiert)edit: noch zu den typedefs: sowas ist schon in ordnung, nicht dass du jetz garkeine typedefs mehr machst!
typedef std::list<ListEntry *>::iterator MeinListenIterator;
-
jupieeeeh, danke für die Hinweise. Zumindest funktioniert dadurch mein Programm jetzt.
Was könnte ich noch Stilmäßig verbessern?struct sSection { string SectionNumber; list<string> SectionText; }; typedef list<sSection*> SectionList; typedef SectionList::iterator SectionListIter; int main(void) { SectionList MainList; SectionListIter MainIter=MainList.begin(); ifstream FileIn("Morgentau.txt"); if (FileIn) // Falls FileIn gültig ist. { string ReadString; do { MainList.push_back(new sSection); MainIter++; getline(FileIn, ReadString); // einlesen der SectionNumber (*MainIter)->SectionNumber = ReadString; do // einlesen des SectionsText { // Trennzeichen zum nächsten Datensatz = [-] getline(FileIn, ReadString); if (ReadString=="[+]") // ich weiss: ganz böse break; // aber heute hoere ich auf if ( ReadString != "[-]") (*MainIter)->SectionText.push_back(ReadString); } while( ReadString != "[-]" ); }while (ReadString != "[+]"); } // Ausgabe der gesamten Liste for(MainIter=MainList.begin(); MainIter != MainList.end();MainIter++) { copy ((*MainIter)->SectionText.begin(), (*MainIter)->SectionText.end(), ostream_iterator<string>(cout, "\n")); } // loeschen der Liste for(MainIter=MainList.begin(); MainIter != MainList.end();MainIter++) delete *MainIter; return 0; }
-
vielleicht ein for_each statt for (...). sonst noch ein paar sachen (aber rein optisch): leerzeichen zwischen operatoren und operanden (nicht *, . und -> operator), 4 zeichen einrückung. naja und du könntest die MainListe statt mit zeigern mit instanzen füttern. dann sparst du dir am schluss das aufräumen. man kann das vertreten, da die struktur im normalfall nicht groß ist.
-
Vllt.
if(InFile) { //ewig viel Code } durch if(!InFile) { // aufräumen }
ersetzten. Wenn Du dann noch Kopien von den Strukturen verwaltest passts
-
@Korbinian mit dem for_each komme ich nicht soganz klar. Die ersten zwei Parameter sind mir klar, aber bei dem dritten habe ich Probleme. Was muß ich da einsetzen um zum Beispiel die Liste auszugeben?
@Knuddelbaer ähm, Kopien von den Strukturen?
-
for_each beispiel, guckst du hier: http://www.josuttis.com/libbook/algo/foreach1.cpp.html
-
danke, jetzt funktioniert es.