Maximale Array Größe erreicht?! Was tun...
-
Hallo,
folgendes Problem...Ich muss für mein kleines Programm eine Datei, die ca. 200 MB Groß ist analysieren. Dafür muss ich zu anfang jede Zeile der Datei in ein Array schreiben. Wir kommen da auf weit mehr als 1.000.000 Zeilen.
Leider stürzt das Programm nach 100.000 Zeilen immer ab. Was kann ich dagegen tun?
Hier Mal mein Programm:
#include <fstream> #include <iostream> #include <string> #include <sstream> #include <cmath> using namespace std; int main(int argc, char *argv[]) { // Definitionen ifstream f; // Datei-Handle string s; size_t pos1; size_t pos2; // Öffne die Datei und schreibe Zeile für Zeile in das Array (array) string array[100000]; // Größe des Arrays (array) int i = 0; // Anzahl der Zeilen im Array (array) f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile array[i] = s; // Schreibe Zeile in das Array i++; } cout<<i; f.close(); // Datei wieder schließen // Suche nach Zeile <indep acfrequency xx> und speichere die nächsten xx Zeilen in dem Array (acfrequency) und die Anzahl in acfrequency_anzahl string abgl1 = "<indep acfrequency "; // Anfang string abgl2 = ">"; // Ende int acfrequency_anzahl; // Anzahl der Frequenzen for (int p=0; p<i; p++){ // Komplettes Array wird durchlaufen pos1 = array[p].find(abgl1); pos2 = array[p].find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string acfrequency_str = array[p].substr(int(pos1)+19, int(pos2)-int(pos1)-1); stringstream acfrequency_ss(acfrequency_str); acfrequency_ss >> acfrequency_anzahl; string acfrequency[acfrequency_anzahl]; p++; for(int q=0; q<acfrequency_anzahl; q++){ acfrequency[q]=array[p+q]; } pos1 = string::npos; pos2 = string::npos; break; } } // Suche nach Zeile <indep phase_urm_var 37> und speichere die nächsten xx Zeilen in dem Array (phase_urm_var) und die Anzahl in phase_urm_var_anzahl abgl1 = "<indep phase_urm_var "; // Anfang abgl2 = ">"; // Ende int phase_urm_var_anzahl; // Anzahl der Phasen for (int p=0; p<i; p++){ // Komplettes Array wird durchlaufen pos1 = array[p].find(abgl1); pos2 = array[p].find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string phase_urm_var_str = array[p].substr(int(pos1)+21, int(pos2)-int(pos1)-1); stringstream phase_urm_var_ss(phase_urm_var_str); phase_urm_var_ss >> phase_urm_var_anzahl; string phase_urm_var[phase_urm_var_anzahl]; p++; for(int q=0; q<phase_urm_var_anzahl; q++){ phase_urm_var[q]=array[p+q]; } pos1 = string::npos; pos2 = string::npos; break; } } // Suche nach Zeile <indep uq xx> und speichere die nächsten xx Zeilen in dem Array (uq) und die Anzahl in uq_anzahl int uq_anzahl; // Anzahl der unterschiedlichen Spannungsquellen abgl1 = "<indep uq "; abgl2 = ">"; for (int p=0; p<i; p++){ // Komplettes Array wird durchlaufen pos1 = array[p].find(abgl1); pos2 = array[p].find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string uq_str = array[p].substr(int(pos1)+10, int(pos2)-int(pos1)-1); stringstream uq_ss(uq_str); uq_ss >> uq_anzahl; pos1 = string::npos; pos2 = string::npos; break; } } string uq[uq_anzahl]; for (int p=0; p<i; p++){ // Komplettes Array wird durchlaufen pos1 = array[p].find(abgl1); pos2 = array[p].find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ p++; for(int q=0; q<uq_anzahl; q++){ uq[q]=array[p+q]; } pos1 = string::npos; pos2 = string::npos; break; } } // Suche nach Zeile <dep umeneu acfrequency phase_urm_var uq> und speichere die nächsten acfrequency_anzahl*phase_urm_var_anzahl in einer Datei mit uq[0] long double zahl; long double ehoch; long double gzahl; abgl1 = "<dep umeneu acfrequency phase_urm_var uq>"; int umeneu_anzahl = acfrequency_anzahl*phase_urm_var_anzahl*uq_anzahl; double umeneu[umeneu_anzahl]; for (int p=0; p<i; p++){ pos1 = array[p].find(abgl1); if(pos1 != string::npos){ p++; for(int q=0; q<umeneu_anzahl; q++){ string zahlvorz_str = array[p+q].substr(2, 1); string zahl_str = array[p+q].substr(3, 13); string ehochvorz_str = array[p+q].substr(17, 1); string ehoch_str = array[p+q].substr(18, 3); stringstream zahl_ss(zahl_str); zahl_ss >> zahl; stringstream ehoch_ss(ehoch_str); ehoch_ss >> ehoch; if(zahlvorz_str=="+"){ zahl = 0 + zahl; } else{ zahl = 0 - zahl; } if(ehochvorz_str=="+"){ ehoch = pow(10, 0+ehoch); } else{ ehoch = pow(10, 0-ehoch); } gzahl = zahl * ehoch; umeneu[q]=gzahl; } pos1 = string::npos; pos2 = string::npos; break; } } // Uq, Ua in die Datei ready.csv schreiben stringstream ss; ss <<"ready.csv" ; string filename = ss.str(); ofstream fout; fout.open(filename.c_str(), ios::trunc); for(int q=0; q<uq_anzahl; q++){ long double avg=0; for(int p=0; p<(acfrequency_anzahl*phase_urm_var_anzahl); p++){ avg = avg + umeneu[p*(q+1)]; } avg = avg / (acfrequency_anzahl*phase_urm_var_anzahl); fout<< uq[q] <<";" <<avg <<endl; } fout.close(); // Dos Fenster nicht schließen cin.get(); cin.get(); }
-
Es ist mit
string array[100000];wenig überraschend, dass 100000 Zeilen die Grenze sind. Benutz besser
#include <deque> #include <string> ... std::deque<std::string> array; // Vielleicht auch einen sprechenderen Variablennamen wählen ... while(getline(f, s)) { array.push_back(s); ++i; }Oder, wenn du die Zeilenzahl vorher abschätzen kannst, std::vectorstd::string mit entsprechendem reserve-Aufruf.
-
seldon schrieb:
Es ist mit
string array[100000];wenig überraschend, dass 100000 Zeilen die Grenze sind. Benutz besser
#include <deque> #include <string> ... std::deque<std::string> array; // Vielleicht auch einen sprechenderen Variablennamen wählen ... while(getline(f, s)) { array.push_back(s); ++i; }Oder, wenn du die Zeilenzahl vorher abschätzen kannst, std::vectorstd::string mit entsprechendem reserve-Aufruf.
Jetzt schafft er nicht Mal mehr die 100.000 Tausend, sondern macht schon bei 20.000 schlapp

-
Javun schrieb:
Jetzt schafft er nicht Mal mehr die 100.000 Tausend, sondern macht schon bei 20.000 schlapp

Nein, warum sollte er? Der Code ist übrigens echt hässlich. Kann sein, dass er da "schlapp macht" (was auch immer das bedeuten soll) weil du deine Array indizes nicht unter Kontrolle hast. Mir würde es bei dem Code schwer fallen.
-
Das Thema
std::dequehatten wir schon ein paar Mal hier Forum, mMn ist das kein Container, der für viele Elemente benutz werden kann. Bei den Implementationen, die ich bisher gesehen habe, ist der Overhead für einzelne Elemente einfach riesig und verschlingt Unmengen an Speicher.
Kannst du nicht besser die Datei zeilenweise einlesen und die Zeilen separat auswerten?PS:
Was ist denn das für eine Datendatei? XML?
-
versuchs doch mal mit nem vector und mach am anfang nen großen reserve.
#include <vector> #include <string> ... std::vector<std::string> array; // Vielleicht auch einen sprechenderen Variablennamen wählen array.reserve(200000); ... while(getline(f, s)) { array.push_back(s); ++i; }Ein großes Problem ist, dass bei deiner ersten Lösung
string array[100000];das array of dem stack angelegt wird und der stack normalerweise ~1MB groß ist. Das kann eng werden..
-
Falls std::vector nicht hilf, dann nimm eine einfache Liste. Falls du random access benoetigst, bist du mit einer map bei 10^6 Eintraegen immer noch gut beraten. Darueber hinaus sollte jede Zeile einzeln verarbeitet werden, so dass die ganze Datei nicht im Speicher gehalten werden muss. Letztendlich gibt es noch memory maped files, aber propiere dich erstmal an den genannten Loesungsvorschlaegen.
Desweiteren scheint deine Vorgehensweise ineffizient. So wie ich es sehe, reicht es die Datei einmal zeilenweise zu durchlaufen und auf das Muster "<indep acfrequency", "<indep phase_urm_var" , ... zu pruefen und die entsprechende Aktion auszufuehren.
-
DocShoe schrieb:
Das Thema
std::dequehatten wir schon ein paar Mal hier Forum, mMn ist das kein Container, der für viele Elemente benutz werden kann. Bei den Implementationen, die ich bisher gesehen habe, ist der Overhead für einzelne Elemente einfach riesig und verschlingt Unmengen an Speicher.Der Speicheroverhead einer Deque im Vergleich zu einem Vektor beträgt bei gcc 4.6 rund 0,195 Prozent. Der Laufzeitnachteil bei der Adressierung ist etwas größer; er läuft auf zwei Array-Zugriffe statt eines hinaus, dafür muss bei Anlegen am Anfang die Deque nicht alle Nase lang verlegt werden. Außerdem, da Random-Access hier ja nicht gefragt zu sein scheint, kann man statt eines Index-Zugriffes schlicht Iteratoren benutzen, womit sich das Problem noch etwas verringern dürfte. Es sollte mich sehr wundern, wenn ausreichend neue Compiler da großartig andere Verfahren benutzten, wobei die Blockgröße variieren mag. Es gab bei uralten MSVCs, wenn ich das richtig im Kopf habe, mal höchst ineffiziente Deque-Implementationen, das ist aber inzwischen Geschichte.
Was das Code-Problem angeht, so kann ich mir nicht vorstellen, dass eine deque bei 20000 Elementen schlapp machen soll; das Problem wird an anderer Stelle liegen. Mein Verdacht fällt auf Dinge wie
p++; for(int q=0; q<acfrequency_anzahl; q++){ acfrequency[q]=array[p+q]; }...wo p allein schon über das Ende der Deque hinauszeigen kann und nicht geprüft wurde, ob acfrequency_anzahl überhaupt korrekt eingelesen werden konnte. Ohne die Eingabedaten zu kennen, ist es für mich allerdings schwer, das mit Sicherheit zu sagen.
-
Natürlich wird keine
queuebei 20K Elementen dicke Backen machen, ich weise nur daraufhin, dass die Verwendung vondequestattvectorandere Probleme mit sich bringen kann. Wenn einvectoraufgrund der großen Datenmengen keinen genügend großen linearen Speicherbereich bekommt kann es genauso gut passieren, dassdequewegen des erhöhten Verwaltungsoverheads auch nicht funktioniert. Der knapp 0.2% große Overhead vom gcc ist natürlich sehr gut, beim SGI STLport und der Dinkumware STL Port ist er wesentlich(!) größer.
Ich bau mal einen Testfall, wenn ich Zeit dazu habe und poste die Ergebnisse.
-
Habe den Code jetzt aktuallisiert und mache es jetzt Zeile für Zeile ohne die ganze Datei in ein Array einzulesen.
Falls noch jmd. Verbesserungsvorschläge hat immer her damit

Hier der Code:
#include <fstream> #include <iostream> #include <string> #include <sstream> #include <cmath> using namespace std; int main(int argc, char *argv[]) { // Definitionen ifstream f; // Datei-Handle string s; size_t pos1; size_t pos2; // Anzahl der Frequenzen ermitteln int acfrequency_anzahl; // Anzahl der Frequenzen string abgl1 = "<indep acfrequency "; // Anfang string abgl2 = ">"; // Ende f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile pos1 = s.find(abgl1); pos2 = s.find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string acfrequency_str = s.substr(int(pos1)+19, int(pos2)-int(pos1)-1); stringstream acfrequency_ss(acfrequency_str); acfrequency_ss >> acfrequency_anzahl; pos1 = string::npos; pos2 = string::npos; break; } } f.close(); // Datei wieder schließen cout<<"Anzahl der Frequenzen: "<<acfrequency_anzahl<<endl; // Anzahl der Phasen ermitteln int phase_urm_var_anzahl; // Anzahl der Phasen abgl1 = "<indep phase_urm_var "; // Anfang abgl2 = ">"; // Ende f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile pos1 = s.find(abgl1); pos2 = s.find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string phase_urm_var_str = s.substr(int(pos1)+21, int(pos2)-int(pos1)-1); stringstream phase_urm_var_ss(phase_urm_var_str); phase_urm_var_ss >> phase_urm_var_anzahl; pos1 = string::npos; pos2 = string::npos; break; } } f.close(); // Datei wieder schließen cout<<"Anzahl der Phasen: "<<phase_urm_var_anzahl<<endl; // Anzahl der Eingangsspannungen ermitteln int uq_anzahl; // Anzahl der unterschiedlichen Spannungsquellen abgl1 = "<indep uq "; abgl2 = ">"; f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile pos1 = s.find(abgl1); pos2 = s.find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ string uq_str = s.substr(int(pos1)+10, int(pos2)-int(pos1)-1); stringstream uq_ss(uq_str); uq_ss >> uq_anzahl; pos1 = string::npos; pos2 = string::npos; break; } } f.close(); // Datei wieder schließen cout<<"Anzahl der Spannungen: "<<uq_anzahl<<endl; // Eingangsspanunngen in das Array uq schreiben double uq[uq_anzahl]; abgl1 = "<indep uq "; abgl2 = ">"; f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile pos1 = s.find(abgl1); pos2 = s.find(abgl2); if(pos1 != string::npos && pos2 != string::npos){ for(int q=0; q<uq_anzahl; q++){ getline(f, s); double zahl; double ehoch; double gzahl; string zahlvorz_str = s.substr(2, 1); string zahl_str = s.substr(3, 13); string ehochvorz_str = s.substr(17, 1); string ehoch_str = s.substr(18, 3); stringstream zahl_ss(zahl_str); zahl_ss >> zahl; stringstream ehoch_ss(ehoch_str); ehoch_ss >> ehoch; if(zahlvorz_str=="+"){ zahl = 0 + zahl; } else{ zahl = 0 - zahl; } if(ehochvorz_str=="+"){ ehoch = pow(10, 0+ehoch); } else{ ehoch = pow(10, 0-ehoch); } uq[q]=zahl * ehoch; } pos1 = string::npos; pos2 = string::npos; break; } } f.close(); // Datei wieder schließen // Ergebnisse mitteln und in das Array ua schreiben double ua[uq_anzahl]; int avg_anzahl = acfrequency_anzahl*phase_urm_var_anzahl; abgl1 = "<dep umeneu acfrequency phase_urm_var uq>"; f.open("rausch_simu.dat", ios::in); // Öffne Datei aus Parameter while (!f.eof()) // Solange noch Daten vorliegen { getline(f, s); // Lese eine Zeile pos1 = s.find(abgl1); if(pos1 != string::npos){ for(int q=0; q<uq_anzahl; q++){ double gzahl; for(int p=0; p<avg_anzahl; p++){ getline(f, s); long double zahl; long double ehoch; string zahlvorz_str = s.substr(2, 1); string zahl_str = s.substr(3, 13); string ehochvorz_str = s.substr(17, 1); string ehoch_str = s.substr(18, 3); stringstream zahl_ss(zahl_str); zahl_ss >> zahl; stringstream ehoch_ss(ehoch_str); ehoch_ss >> ehoch; if(zahlvorz_str=="+"){ zahl = 0 + zahl; } else{ zahl = 0 - zahl; } if(ehochvorz_str=="+"){ ehoch = pow(10, 0+ehoch); } else{ ehoch = pow(10, 0-ehoch); } gzahl = zahl * ehoch; ua[q] = ua[q] + gzahl; } ua[q] = ua[q] / avg_anzahl; } pos1 = string::npos; break; } } f.close(); // Datei wieder schließen // Uq, Ua in die Datei ready.csv schreiben stringstream ss; ss <<"ready.csv" ; string filename = ss.str(); ofstream fout; fout.open(filename.c_str(), ios::trunc); cout<<endl <<"Uq -------> Ua" <<endl; for(int q=0; q<uq_anzahl; q++){ fout<<uq[q] <<";" <<ua[q] <<endl; cout<<uq[q] <<"------->" <<ua[q] <<endl; } fout.close(); cout<<endl <<"ready.csv Datei wurde erfolgreich erstellt." <<endl; // Dos Fenster nicht schließen cin.get(); cin.get(); }
-
Javun schrieb:
Falls noch jmd. Verbesserungsvorschläge hat immer her damit

Unmengen:
1. Definitionen gehören nicht an den Anfang einer Funktion, sondern dahin, wo sie gebraucht werden.
2. Dein Einlesen sieht falsch aus. Es liest die letzte Zeile doppelt und es kommt nicht mit unerwarteten Fehlern zurecht. Einfacher wäre hier besser. Außerdem könntest du dir viel Code sparen, wenn du die Konstruktoren und Destruktoren des Dateistreams ausnutzen würdest.
3. Fällt dir nichts auf, wenn du Zeilen 18-38, 41-61 und 87-130, 133-178 vergleichst? Warum machst du das nicht in einem Rutsch?
4. Mit 2+3 zusammenhängend: Variablenrecycling ist ganz schlechter Stil.
5. Ein paar mehr Buchstaben täten deinen Variablennamen auch gut.
6. Wie wäre es, oft benutzte Funktionalität mal in eine Funktion zu packen? Ich bin beim Lesen bisher schon 4x an der gleichen Copy&Paste Einleseroutine vorbeigekommen.
7. Du kannst Memberfunktionsaufrufe anneinander hängen: ss.str().c_str()Fazit: Sieht eher wie ein Scherzprogramm aus. Das alles könnte man auch als Anfänger ganz leicht von 200 auf 50 Zeilen kürzen
-
SeppJ schrieb:
Javun schrieb:
Falls noch jmd. Verbesserungsvorschläge hat immer her damit

Unmengen:
1. Definitionen gehören nicht an den Anfang einer Funktion, sondern dahin, wo sie gebraucht werden.
2. Dein Einlesen sieht falsch aus. Es liest die letzte Zeile doppelt und es kommt nicht mit unerwarteten Fehlern zurecht. Einfacher wäre hier besser. Außerdem könntest du dir viel Code sparen, wenn du die Konstruktoren und Destruktoren des Dateistreams ausnutzen würdest.
3. Fällt dir nichts auf, wenn du Zeilen 18-38, 41-61 und 87-130, 133-178 vergleichst? Warum machst du das nicht in einem Rutsch?
4. Mit 2+3 zusammenhängend: Variablenrecycling ist ganz schlechter Stil.
5. Ein paar mehr Buchstaben täten deinen Variablennamen auch gut.
6. Wie wäre es, oft benutzte Funktionalität mal in eine Funktion zu packen? Ich bin beim Lesen bisher schon 4x an der gleichen Copy&Paste Einleseroutine vorbeigekommen.
7. Du kannst Memberfunktionsaufrufe anneinander hängen: ss.str().c_str()Fazit: Sieht eher wie ein Scherzprogramm aus. Das alles könnte man auch als Anfänger ganz leicht von 200 auf 50 Zeilen kürzen
Priorität war, dass das Programm funktioniert und das tut es. Ob nun 200 oder 50 Zeilen interessiert eigentlich herzlich wenig. Auch ist es relativ unwichtig wie der Quellcode aussieht. Ein Scherzprogramm würde ich das nicht nennen.
1. Wo die Definitionen hingehören ist doch herzlich egal. Natürlich könnte ich jetzt 1 Stunde meiner Zeit investestieren um den Code schöner aussehen zu lassen, dass bringt demjenigen, der später die .exe ausführt aber herzlichst wenig.
2. Was sieht den da falsch aus? Ich verstehe auch nicht ganz, wo ich die letzte Zeile doppelt lese?! Ich würde ja sonst nicht auf die korrekten Ergebnisse kommen. Was für unerwartete Fehler sollte es denn geben, wenn die auszuwertende Datei immer gleich aussieht?! Wie man mit Konstruktoren und Destruktoren des Dateistreams arbeitet weiß ich als Anfänger leider nicht, aber wie das geht, dass wäre eine Antwort auf meine Frage gewesen...
3. Weil mir nicht ganz klar ist, wie das in einem Rutsch gehen soll?! Siehe Änderung von der ersten Version zur jetzigen.
4. Mag sein, das lässt sich leicht ändern, aber es funktioniert und den Quellcode sieht niemand außer ich

5. Siehe 4.
6. Wenn ich da signifikante Vorteile sehen würde, dann hätte ich es sicherlich gemacht.
7. Verstehe nicht ganz, was Du damit aussagen willst?!
-
Dein Code ist halt mies wartbar, das ist das Problem.
-
Javun schrieb:
Priorität war, dass das Programm funktioniert und das tut es. Ob nun 200 oder 50 Zeilen interessiert eigentlich herzlich wenig.
Nein. Schlechte Einstellung, die dir in Zukunft garantiert Probleme machen wird.
Auch ist es relativ unwichtig wie der Quellcode aussieht.
Falls du mit Objektcode den Quellcode meinst: Nein. Schlechte Einstellung, die dir in Zukunft garantiert Probleme machen wird.
Falls du wirklich den Objektcode meinstest: Ja.1. Wo die Definitionen hingehören ist doch herzlich egal.
Nein. Schlechte Einstellung sdie dir in Zukunft Probleme machen wird.
Natürlich könnte ich jetzt 1 Stunde meiner Zeit investestieren um den Code schöner aussehen zu lassen, dass bringt demjenigen, der später die .exe ausführt aber herzlichst wenig.
Nein. Schlechte Einstellung, die dir in Zukunft garantiert Probleme machen wird.
2. Was sieht den da falsch aus? Ich verstehe auch nicht ganz, wo ich die letzte Zeile doppelt lese?!
Du prüfst auf Fehler, dann liest du ein, dann verarbeitest du. Was passiert wohl, wenn ein Lesefehler, zum Beispiel Dateiende, auftritt?
Ich würde ja sonst nicht auf die korrekten Ergebnisse kommen.
Dann hast du Glück, weil in deiner letzten Zeile nichts steht, was du verarbeitest (vermutlich eine Leerzeile)
Was für unerwartete Fehler sollte es denn geben, wenn die auszuwertende Datei immer gleich aussieht?!
Wenn sie immer gleich aussieht, warum ist es dann eine externe Datei? Irgendwas wirst du doch ändern.
Wie man mit Konstruktoren und Destruktoren des Dateistreams arbeitet weiß ich als Anfänger leider nicht, aber wie das geht, dass wäre eine Antwort auf meine Frage gewesen...
Ja, eigentlich ist das das Stichwort für Pi, der das jedem Anfänger unter die Nase reibt. Eigentlich komisch, dass er noch nichts geschrieben hat. Ansonsten empfehle ich mal, alte Threads hier anzugucken oder ein besseres Buch zu lesen. Zum Erklären der Details bin ich selber gerade zu faul.
3. Weil mir nicht ganz klar ist, wie das in einem Rutsch gehen soll?! Siehe Änderung von der ersten Version zur jetzigen.
Wieso liest du immer wieder von vorne ein? Geh doch einmal durch und guck, was in der Zeile steht!
4. Mag sein, das lässt sich leicht ändern, aber es funktioniert und den Quellcode sieht niemand außer ich

Nein. Schlechte Einstellung, die dir in Zukunft garantiert Probleme machen wird.
Auch ist es relativ unwichtig wie der Quellcode aussieht.
5. Siehe 4.
[/quote]Nein. Schlechte Einstellung, die dir in Zukunft garantiert Probleme machen wird.Auch ist es relativ unwichtig wie der Quellcode aussieht.
6. Wenn ich da signifikante Vorteile sehen würde, dann hätte ich es sicherlich gemacht.[/quote]Wie siehst du denn keine Vorteile? Das erhöht die abstraktion und vermeidet Codeduplizierung. Das erhöht die Wartbarkeit ganz enorm! Das ist einer der größten Vorteile die man überhaupt haben kann! Gerade dein Quellcode ist ein Musterbeispiel an Unwartbarkeit, daher ist es auch so schwer, dir zu helfen.
7. Verstehe nicht ganz, was Du damit aussagen willst?!
Du benutzt unnötige, temporäre Werte wie in Zeile 183, weil du dies nicht zu wissen scheinst.
-
SeppJ schrieb:
Ja, eigentlich ist das das Stichwort für Pi, der das jedem Anfänger unter die Nase reibt. Eigentlich komisch, dass er noch nichts geschrieben hat.
Findest du nicht okay, dass ich das tue? (_dass_ ich es tue, nicht _wie_!)
Ich hab mich nicht gemeldet, da der TE ja offenbar keine Hilfe annimmt. Ansonsten hätte ich ihm das Programm vermutlich mithilfe von boost::spirit komplett neu geschrieben. Da er aber nicht mal bekanntgibt, was für Daten er überhaupt parsen will, ist das Zeitverschwendung.
-
stringstream ss; ss <<"ready.csv" ; string filename = ss.str(); ofstream fout; fout.open(filename.c_str(), ios::trunc);Wieso kritisiert eigentlich das keiner? Komplett redundanter Code.
-
Wahrscheinlich weil du der erste bist, der so weit gelesen hat

-
314159265358979 schrieb:
Wahrscheinlich weil du der erste bist, der so weit gelesen hat

+1. Ich hatte ja schon den temporären Zwischenstring bemängelt, aber dass das ganze Konstrukt derart unnötig ist, war mir gar nicht aufgefallen.
-
Javun schrieb:
Falls noch jmd. Verbesserungsvorschläge hat immer her damit

Hallo Javun,
Damit meintest Du doch Deinen Code und SeppJ hat sich die Mühe gemacht einige Verbesserungsvorschläge aufzuführen. Und spätestens Deine Reaktion
Javun schrieb:
Priorität war, dass das Programm funktioniert und das tut es. Ob nun 200 oder 50 Zeilen interessiert eigentlich herzlich wenig. Auch ist es relativ unwichtig wie der Quellcode aussieht.
entlarvt Dich als Anfänger.
Aber das ist nicht schlimm, jeder hat mal klein angefangen.
Interessant ist vor allem diese Sequenz:
Javun schrieb:
getline(f, s); double zahl; double ehoch; double gzahl; string zahlvorz_str = s.substr(2, 1); string zahl_str = s.substr(3, 13); string ehochvorz_str = s.substr(17, 1); string ehoch_str = s.substr(18, 3); stringstream zahl_ss(zahl_str); zahl_ss >> zahl; stringstream ehoch_ss(ehoch_str); ehoch_ss >> ehoch; if(zahlvorz_str=="+"){ zahl = 0 + zahl; } else{ zahl = 0 - zahl; } if(ehochvorz_str=="+"){ ehoch = pow(10, 0+ehoch); } else{ ehoch = pow(10, 0-ehoch); } uq[q]=zahl * ehoch;diese 25 Zeilen kann man im Prinzip ersetzen durch
f.ignore(2) >> uq[q]; f.ignore( numeric_limits< streamsize >::max(), '\n' );evt. kann man selbst dies noch vereinfachen, indem man die zweite Zeil weglässt, aber ich kenne Dein Dateiformat natürlich nicht.
Und zu SeppJs Punkt 2 und
while (!f.eof())habe ich hier schon mal was verfasst.
Nein es ist nicht egal, wie der Quellcode aussieht.
Gruß
Werner
-
So dann meld ich mich auch Mal zu Wort. Also zunächst einmal bin ich wirklich blutiger Anfänger, was die Programmierung angeht. Leider war es mir auch nicht möglich mich innerhalb von 2 Wochen in soetwas wie objektorientiere Programmierung einzuarbeiten, aber ich hatte gehofft, dass ich mit meinem Wissen und ein bisschen Hilfe ein funktionierenden Programm auf die Beine stellen kann.
Was soll das Programm genau machen?
Es soll eine Qucs Dataset Datei auslesen,
in der Zeile <indep acfrequency x> steht die Anzahl der Frequenzen (x).
In der Zeile <indep phase_urm_var y> steht die Anzahl der Phasen (y).
In der Zeile <indep uq z> steht die Anzahl der Eingangsspannungen (z).
Ab der Zeile <dep umeneu acfrequency phase_urm_var uq> stehen alle Ergebnisse der Simulation, die Simulation hat genau soviel Ergebnisse wie x*y*z. Dier Ergebnisse sollen nun gemittelt werden über Phase und Frequenz, d.h. für jede Eingangsspannung soll genau eine Ausgangsspannung als Ergebnis herauskommen. Also mussen immer x*y Zeilen gemittelt werden usw...Die Zahlen in der Datei haben immer das Format:
+2.62377776236e-008Leider bekomme ich an einigen Stellen wirklich falsche Ergebnisse raus, daher wäre ich euch für Hilfe sehr dankbar. Ich bitte euch nur wenn möglich bei meinem Anfängercode zu bleiben, denn den Code verstehe ich. Es bringt mir nicht viel, wenn ich einen Code mit Konstrukturen usw. perfekt programmiert habe, ich jedoch keine Änderung mehr vornehmen kann, da ich den Code nicht verstehe und mich da erst einarbeiten kann.
Deswegen habe ich auch Schrittweise versucht das Problem zu lösen und nicht gleich alles in einem Rutsch. Für den geübten sollte das natürlich kein Problem sein, aber ich habe da noch leider meine Probleme mit, daher denke ich das auch doppelte Schritte nicht unbedingt schädlich sind solange sie meinem Verständnis dienen oder sehe ich das falsch?
Beispiel der Datei:
<Qucs Dataset 0.0.15> <indep Urm 1> +5.30751744861e-007 </indep> <indep y 1> +1.78631210467e-008 </indep> <indep acfrequency 2> +6.72000000000e+002 +6.82000000000e+002 </indep> <indep phase_urm_var 2> -1.80000000000e+002 +1.80000000000e+002 </indep> <indep uq 2> +1.00000000000e-015 +1.00000000000e-007 </indep> <dep umeneu acfrequency phase_urm_var uq> +1.67213405084e-008 +1.59303541061e-008 +1.67213405084e-008 +1.59303541061e-008 +1.98703688153e-008 +1.89304207570e-008 +1.98703688153e-008 +1.89304207570e-008 </dep> <dep U_ME1.v acfrequency phase_urm_var uq> +1.67213405084e-008+j2.04770597862e-024 -1.59303541061e-008-j1.95084128199e-024 +1.67213405084e-008-j2.04770597939e-024 -1.59303541061e-008+j1.95084128199e-024 +1.98703688153e-008+j2.04770597708e-024 -1.89304207570e-008-j1.95084128276e-024 +1.98703688153e-008-j2.04770598324e-024 -1.89304207570e-008+j1.95084128276e-024 </dep> <dep V1.i acfrequency phase_urm_var uq> +1.20871499877e-029-j9.87023297137e-014 -1.16867391765e-029+j9.54326193230e-014 -1.20871499877e-029-j9.87023297137e-014 +1.16867391765e-029+j9.54326193230e-014 +1.20871499877e-029-j1.17290338855e-013 -1.16867391765e-029+j1.13404863803e-013 -1.20871499877e-029-j1.17290338855e-013 +1.16867391765e-029+j1.13404863803e-013 </dep> <dep V2.i acfrequency phase_urm_var uq> +3.05172413793e-013+j9.87023297137e-014 +3.05172413793e-013-j9.54326193230e-014 +3.05172413793e-013+j9.87023297137e-014 +3.05172413793e-013-j9.54326193230e-014 +3.05172413793e-013+j1.17290338855e-013 +3.05172413793e-013-j1.13404863803e-013 +3.05172413793e-013+j1.17290338855e-013 +3.05172413793e-013-j1.13404863803e-013 </dep> <dep _net3.v acfrequency phase_urm_var uq> -1.64510637319e-017-j4.94667241197e-019 +7.32282543222e-018-j4.94667241197e-019 +7.72323624342e-018+j4.94667241197e-019 -1.60506529207e-017+j4.94667241197e-019 -1.64510637319e-017+j1.21295118047e-017 +7.32282543222e-018-j1.31188462871e-017 +7.72323624342e-018+j1.31188462871e-017 -1.60506529207e-017-j1.21295118047e-017 </dep> <dep _net5.v acfrequency phase_urm_var uq> +5.30999999984e-007-j4.94602214599e-019 +5.31000000007e-007-j4.94602214599e-019 +5.31000000008e-007+j4.94602214599e-019 +5.30999999984e-007+j4.94602214599e-019 +5.30999999984e-007+j1.21295768313e-017 +5.31000000007e-007-j1.31187812605e-017 +5.31000000008e-007+j1.31187812605e-017 +5.30999999984e-007-j1.21295768313e-017 </dep> <dep _net7.v acfrequency phase_urm_var uq> +1.67213394919e-008-j4.94665193491e-019 -1.59303550987e-008-j4.94669192038e-019 +1.67213395161e-008+j4.94665193491e-019 -1.59303551221e-008+j4.94669192038e-019 -8.01296312012e-008+j1.21295138524e-017 -1.18930420750e-007-j1.31188482379e-017 -8.01296311770e-008+j1.31188442394e-017 -1.18930420773e-007-j1.21295098538e-017 </dep> <dep _net0.v acfrequency phase_urm_var uq> -2.34580397786e-028+j9.43255890062e-018 +1.40412606860e-028+j2.06676039130e-018 +2.34580397786e-028+j6.55264687996e-018 -1.40412606860e-028-j5.23805174582e-018 -3.64817874990e-027+j2.74845250725e-017 -4.47757913230e-027+j1.23666810299e-017 +3.64817874990e-027+j6.36629963156e-017 +4.47757913230e-027+j5.05509262921e-018 </dep> <dep _net1.v acfrequency phase_urm_var uq> -1.67213405084e-008+j9.43255685292e-018 +1.59303541061e-008+j2.06676234214e-018 -1.67213405084e-008+j6.55264892767e-018 +1.59303541061e-008-j5.23805369666e-018 -1.98703688153e-008+j2.74845230248e-017 +1.89304207570e-008+j1.23666829808e-017 -1.98703688153e-008+j6.36629983633e-017 +1.89304207570e-008+j5.05509067837e-018 </dep> <dep _net4.v acfrequency phase_urm_var uq> -1.01645106429e-015-j4.94667241197e-019 -9.92677175497e-016-j4.94667241197e-019 -9.92276763832e-016+j4.94667241197e-019 -1.01605065263e-015+j4.94667241197e-019 -1.00000000016e-007+j1.21295118047e-017 -9.99999999927e-008-j1.31188462871e-017 -9.99999999923e-008+j1.31188462871e-017 -1.00000000016e-007-j1.21295118047e-017 </dep> <dep _net2.v acfrequency phase_urm_var uq> +1.00000000000e-015 +1.00000000000e-015 +1.00000000000e-015 +1.00000000000e-015 +1.00000000000e-007 +1.00000000000e-007 +1.00000000000e-007 +1.00000000000e-007 </dep> <dep _net6.v acfrequency phase_urm_var uq> +3.68300032776e-005-j4.90157015602e-019 -3.50877965602e-005-j4.98964115049e-019 +3.68300032776e-005+j4.90157015602e-019 -3.50877965603e-005+j4.98964115049e-019 +4.36659736817e-005+j1.21340220303e-017 -4.17956677725e-005-j1.31231431609e-017 +4.36659736818e-005+j1.31143360615e-017 -4.17956677725e-005-j1.21252149308e-017 </dep>
-
Javun schrieb:
Leider bekomme ich an einigen Stellen wirklich falsche Ergebnisse raus, daher wäre ich euch für Hilfe sehr dankbar.
Magst du das vielleicht erläutern? Was genau kommt bei welcher Eingabe raus und was würdest du erwarten und warum?
Hast du denn auch schon die genannten Fehler (es wurden dir auch Fehler genannt, nicht nur Designschwächen) korrigiert?