Vektor mit daten aus Txt zeilenweise beschreiben (was anderes als push_back)
-
@werner erstmal vielen dank für den Schnelle Codeblock
Ich habe den in Visual C++ 2008 Express importiert und mit Vektor angeschaut, das sieht genauso aus wie bei mir

hier das ergebnis mittendrin
[9](" ","10000"," ","DE"," ","Institut Für Fußbodentechnik"," ","Norbert Strehle"," ")vielleicht bin ich auch zu blöd ich dachte das die Daten aber so intern weg sepichert werden.
[0](" ")
[1]("10000"
[2](" ")
[3]("DE")ich wollte erst alle Daten der Datei einlesen und dann über eine Schleife die DAten dann in der Ausgabe selektieren ist vielleicht umständlich aber ich wollte den Code noch für andere Dateien benutzen
-
Werner_logoff schrieb:
Matthesjimte schrieb:
Wenn ich im Debug Modus anschaue steht da w[0]" " im w[1]" ","Name" im w[2]]" ","Name"," " usw. irgendwann kommt dei Fehlermeldung vector subscript out of range (überlaufen)
letzteres liegt daran, dass Du den vector sofort in der Schleife wieder löschst. Jeder weitere Zugriff ist ein 'subscript out of range'.
Willst Du sowas:
#include <string> #include <fstream> #include <vector> int ausgabe() { using namespace std; const int ZEILEN_PRO_DATENSATZ = 17; fstream eva("c:\\temp\\eva.txt"); ifstream in("c:\\temp\\daten.txt"); while (in) { // -- genau einen Datensatz verarbeiten vector<string> w; // Einen Vektor für die Werte EINES Datensatzes for (string line5; w.size() < ZEILEN_PRO_DATENSATZ && getline(in,line5);) w.push_back (line5); //Zeile in den Vektor übergeben if (in) eva <<"Satzart=CMPK01|ADRESSART=KUNDE|ERP_KEY="<<w[1]<<"|NAME1="<<w[5]<<"|NAME2="<<w[7]<<"|STRASSE="<<w[17]<<"|PLz="<<w[11]<<"|ORT="<<w[9]<<"|LAND="<<w[3]<< '\n'; } return 0; }Matthes schrieb:
Die Quelldatei ist ungefähr so aufgebaut (mit leerzeilen)
leer
Name
leer
leer
Strasse
Ort
leerstimmt nicht überein mit "... ERP_KEY="<<w[1]<<"|NAME1="<<w[5]<<"|NAME2="<<w[7]<<"|STRASSE="<<w[17] ..." ??
Du hast recht ich dachte aber das es nicht so wichtig und der Fehler nur beim push_back lag (eigentlich hatte ich gehofft das der Satz kommt dann nehm doch einfach das oder das). ISt wohl doch ein bißchen schwerer zu lösen.
-
Matthesjimte schrieb:
Ich habe den in Visual C++ 2008 Express importiert und mit Vektor angeschaut, das sieht genauso aus wie bei mir

ja im Prinzip sollte der genauso aussehen. der Unterschied ist nur, dass bei Dir ALLE Zeilen des Dokuments im vector sind und bei meinem Code nur jeweils die 17 (eines Datenblocks)
Matthesjimte schrieb:
hier das ergebnis mittendrin
[9](" ","10000"," ","DE"," ","Institut Für Fußbodentechnik"," ","Norbert Strehle"," ")Die [9] bedeutet, dass der vector 9 Elemente enthält. Wen Du auf das [+] vor dem vector im Debug-Fenster klickst, so siehst Du sie einzeln.
Matthesjimte schrieb:
vielleicht bin ich auch zu blöd ich dachte das die Daten aber so intern weg sepichert werden.
[0](" ")
[1]("10000"
[2](" ")
[3]("DE")ja genauso werden sie gespeichert, in diesem Fall sind die [#] die Indizes ...
Matthesjimte schrieb:
ich wollte erst alle Daten der Datei einlesen und dann über eine Schleife die DAten dann in der Ausgabe selektieren ist vielleicht umständlich aber ich wollte den Code noch für andere Dateien benutzen
kannst Du auch machen, brauchst Du aber nicht, braucht mehr Speicher und ist evt. etwas schwieriger zu Programmieren.
-
@werner Danke erstmal werde do heute abend noch mal reinschauen
-
@werner Dank dir bin ich jetzt schlauer. das mit dem Plus war ein guter Tipp
Mein Programm steigt aus weil nicht mehr wie 1800 Vectoren eingelesen werden und dann meine Ausgabe auf einen Vektor zugreift der nicht existiert.
Gibt es da eine Grenze? kann man die umgehen
auch wenn nicht schön aussieht hier mein code
int ausgabe() { # include <cstdlib> # include <string> # include <fstream> unsigned int k; int z; int v1=1; int v2=5; int v3=7; int v4=17; int v5=11; int v6=9; int v7=3; char test; fstream eva; eva.open("c:\\temp\\eva.txt"); ifstream in("c:\\temp\\daten.txt"); string line5; // variable für zeileneinlesen vector<string> w; // Einen Vektor für die Werte deklarieren while ( std::getline(in, line5,'\n')) { w.push_back (line5); //Zeile in den Vektor übergeben } for (k=0 ; k<=1000 ; k++) //Vektor hochzählen { z=k*18; v1=z+1; v2=z+5; v3=z+7; v4=z+17; v5=z+11; v6=z+9; v7=z+3; eva <<"Satzart=CMPK01|ADRESSART=KUNDE|ERP_KEY="<<w[v1]<<"|NAME1="<<w[v2]<<"|NAME2="<<w[v3]<<"|STRASSE="<<w[v4]<<"|PLz="<<w[v5]<<"|ORT="<<w[v6]<<"|LAND="<<w[v7]<< '\n'; } return 0; }Die Datei die ich einlesen muss hat 400 zeilen und 17 elemente macht 6800 Daten.
Muss ich mich da am besten von Vektoren verabschieden? oder soll ich die Datei einlesen, erste zeile löschen und wieder schließen. dann wieder aufmachen, löschen usw.? ist aber nicht die feine Art.Fragen über Fragen! und nochmals vielen Dank
für die schnelle Hilfe, hätte schon vor Tagen in Forum schreiben sollen
-
Vektoren haben keine Größenbegrenzung. Deine for-schleife ist komplett falsch. Du führst mysteriöse Rechnungen aus, die letztlich in einer Zugriffsverletzung enden müssen!!!
Mal tachelles, wie sehen nun die Daten wirklich aus? NICHT nur ungefähr. Gib ein komplettes Beispiel, aus mindestens 3 Datensätzen. Dann erst kann dir richtig geholfen werden.
-
Bei der for-Schleife ist der höchste berechnete Index 18017 (v4). Das ist weit mehr als 6800. Das muss ja daneben gehen.
-
#include <string> #include <fstream> #include <vector> int ausgabe() { using namespace std; const int ZEILEN_PRO_DATENSATZ = 17; fstream eva("c:\\temp\\eva.txt"); ifstream in("c:\\temp\\daten.txt"); while (in) { // -- genau einen Datensatz verarbeiten vector<string> w; // Einen Vektor für die Werte EINES Datensatzes for (string line5; w.size() < ZEILEN_PRO_DATENSATZ && getline(in,line5);) w.push_back (line5); //Zeile in den Vektor übergeben if (in) eva <<"Satzart=CMPK01|ADRESSART=KUNDE|ERP_KEY="<<w[1]<<"|NAME1="<<w[5]<<"|NAME2="<<w[7]<<"|STRASSE="<<w[17]<<"|PLz="<<w[11]<<"|ORT="<<w[9]<<"|LAND="<<w[3]<< '\n'; } return 0; }Die Abfrage if(in) sieht für mich komisch aus. Müsste man nicht viel eher überprüfen, ob der Vektor v auch 18 Elemente hat, also der Datensatz komplett ist, dann die Ausgabe nach eva schreiben und abschließend den Vektor v leeren?
Und in einem else-Zweig eine Fehlerbehandlung durchführen?
-
bmario schrieb:
#include <string> #include <fstream> #include <vector> int ausgabe() { using namespace std; const int ZEILEN_PRO_DATENSATZ = 17; fstream eva("c:\\temp\\eva.txt"); ifstream in("c:\\temp\\daten.txt"); while (in) { // -- genau einen Datensatz verarbeiten vector<string> w; // Einen Vektor für die Werte EINES Datensatzes for (string line5; w.size() < ZEILEN_PRO_DATENSATZ && getline(in,line5);) w.push_back (line5); //Zeile in den Vektor übergeben if (in) eva <<"Satzart=CMPK01|ADRESSART=KUNDE|ERP_KEY="<<w[1]<<"|NAME1="<<w[5]<<"|NAME2="<<w[7]<<"|STRASSE="<<w[17]<<"|PLz="<<w[11]<<"|ORT="<<w[9]<<"|LAND="<<w[3]<< '\n'; } return 0; }Die Abfrage if(in) sieht für mich komisch aus. Müsste man nicht viel eher überprüfen, ob der Vektor v auch 18 Elemente hat, also der Datensatz komplett ist, dann die Ausgabe nach eva schreiben und abschließend den Vektor v leeren?
Und in einem else-Zweig eine Fehlerbehandlung durchführen?wenn bool(in)==true ist, so muss der vector ZEILEN_PRO_DATENSATZ Elemente enthalten (17 oder 18 - Matthes ist sich da selber nicht einig). Ansonsten wäre die darüber liegende for-Schleife gar nicht verlassen worden.
Das Leeren des vectors ist unnötig, da der vector lokal exisitiert und mit jedem Schleifendurchlauf der while-Schleife neu angelegt wird. (Nein, das muss nicht zwingend unperfomant sein)Die Abfrage if(w.size()==ZEILEN_PRO_DATENSATZ) .. wäre in diesem Fall gleichbedeutend, enthielte aber eine implizite Redundanz gegenüber den Zeilen darüber. Es wäre ja z.B.: denkbar, dass man in den Code-Zeilen 14-16 nur die Zeilen aus der Datei liest, die man auch wirklich braucht, dann müsste diese Abfrage wieder angepasst werden - ein einfaches if(in) dagegen nicht. Aber ich glaube Matthes kämpft noch mit profaneren Problemen.
-
Werner_logoff schrieb:
wenn bool(in)==true ist, so muss der vector ZEILEN_PRO_DATENSATZ Elemente enthalten (17 oder 18 - Matthes ist sich da selber nicht einig). Ansonsten wäre die darüber liegende for-Schleife gar nicht verlassen worden.
Das klingt logisch, danke.
Werner_logoff schrieb:
Das Leeren des vectors ist unnötig, da der vector lokal exisitiert und mit jedem Schleifendurchlauf der while-Schleife neu angelegt wird. (Nein, das muss nicht zwingend unperfomant sein)
Oha, da hatte ich doch glatt übersehen, dass w lokal ist, in Matthes Version war es das noch nicht

Und du wirst lachen, aber ich hab mich mittlerweile auch gefragt, ob es sinnvoll wäre w nicht lokal zu machen. Was ist denn effizienter, den Vektor komplett zu zerstören, also Konstruktor und Destruktor für jeden Durchlauf in Kauf nehmen, oder die Elemente jeweils zu löschen?Aber ein was fällt mir noch ein:
vector<string> w(ZEILEN_PRO_DATENSATZ+1);mario
-
bmario schrieb:
Aber ein was fällt mir noch ein:
vector<string> w(ZEILEN_PRO_DATENSATZ+1);Das wäre auch eine Möglichkeit, die gleich zeigt, dass die Abfrage if(in) der Abfrage if(w.size()==ZEILEN_PRO_DATENSATZ) überlegen ist. Vergisst man nämlich im letzteren Fall die Abfrage zu ändern, so schießt man sich in's Knie und merkt es vielleicht gar nicht.
Das '+1' ist unnötig.
bmario schrieb:
Was ist denn effizienter, den Vektor komplett zu zerstören, also Konstruktor und Destruktor für jeden Durchlauf in Kauf nehmen, oder die Elemente jeweils zu löschen?
Solche Fragen würde ich bei dem Level, bei dem wir hier gerade diskutieren, ganz ganz weit hinten ansiedeln. (s. Donald Knuth "premature optimization is the root of all evil").
Denk' lieber darüber nach, wie man den Code übersichtlich, einfach und vor allem funktionsfähig gestaltet.