Probleme bei file einlesen
-
Dann ist szBuffer wohl ein string und für Strings gehen die << >> Operatoren nicht. Die Funktionieren nur wenn du mit stringsstream oder ofstreams und Co arbeitest.
Ich vermute jetzt mal das du versuchst ein Array oder ähnlich in einer Datei abzuspeichern und wieder auszulesen. In diesem Fall ist die eleganteste Lösung das ganze mit Binärdateien zu machen. Dann kannst du dir die komplette Schleife schenken und dein komplettes Array mit file.read(...) einlesen. (Ich denke das wäre das elegansteste Vorgehen)
-
samo schrieb:
hmm, ich kann aber nicht
szBuffer >> xmachen, da dann kommt
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion).
Aber mit szBuffer.substr() kann ich auch nicht arbeiten, da ja die float-Zahlen immer wieder unterschiedliche Laenge haben
Den Index, an welchem der Float-Wert beginnt, bekommst du ja durch deine Suche nach dem 'X,Y oder Z' geliefert. Von dort aus musst du das nächste Leerzeichen suchen, dann hast du deinen ganzen Wert.
Alternativ kannst du auch festlegen das jeder Fließkommawert mit einer festen Präzision (z.B.
gespeichert wird.grüße
-
Wie suche ich nach dem naechsten Leerzeichen? mit find('\')?
-
find(" ")
-
std::string::size_type pos = str.find( " ", lastindex ); if ( pos == std::string::npos ) // nich gefundengrüße
-
o.k., er findet jetzt meine Leerzeichen und auch meine X, Y, und Z, aber er liest immer nur das X und auch das zum Teil nicht richtig ein. Die Y und Z bleiben immer auf 0 und ich weiss nicht warum. Kann mir jemand weiterhelfen?
Das ist mein jetziger Code:
string szBuffer; string szValue; string::size_type pos1 = 0; string::size_type pos2 = 0; string::size_type pos3 = 0; float x = 0.; float y = 0.; float z = 0.; while (!file.eof()) { getline(file, szBuffer); pos2 = szBuffer.size(); if (szBuffer.find("X",0) != string::npos) { pos3 = szBuffer.find("X",0); pos1 = szBuffer.find(" ", pos3); x = atof((szBuffer.substr(pos1-pos3,pos1)).c_str()); //if (szBuffer.find("Y",0) != string::npos) //{ pos3 = szBuffer.find("Y",0); pos1 = szBuffer.find(" ", pos3); y = atof((szBuffer.substr(pos1-pos3,pos1)).c_str()); //if (szBuffer.find("Z",0) != string::npos) //{ pos3 = szBuffer.find("Z",0); x = atof((szBuffer.substr(pos2-pos3,pos2)).c_str()); //} //} m_RobotPath->InsertNextPoint(x,y,z); } } }und das die einzulesende Datei
N10G94
N11T01 M6
N12G50 X0.00 Y0.00 Z0.00
N13S2000 M3
N14S1200M3
N15G00X0.000 Y0.000 Z5.000
N16G01X0.000 Y0.000 Z0.000 F100.0
N17G01X54.300 Y0.000 Z0.000
N18G01X54.300 Y0.056 Z0.000
N19G01X38.944 Y0.056 Z0.000
N20G01X38.833 Y0.056 Z-0.013
N21G01X9.389 Y0.056 Z-0.013
.........P.S.: Die einzulesende Datei kann ich nicht aendern, die bekomme ich so von einem anderen Programm das ich nicht beinflussen kann
-
samo schrieb:
Hallo zusammen
ich habe ein file das so aussieht:
N10G94
N11T01 M6
N12G50 X0.00 Y0.00 Z0.00
N13S2000 M3
N14S1200M3
N15G00X-3.667Y-3.667Z5.000
N16G01X-3.667Y-3.667Z0.000F100.0
N17G01X43.000Y-3.667Z0.000
N18G01X43.000Y-3.000Z0.000
N19G01X-3.667Y-3.000Z0.000
N20G01X-3.667Y-2.333Z0.000
.........Was ich jetzt moechte sind nur die x, y, und z Werte auslesen.
Du kannst Dir eine Menge Arbeit sparen, wenn Du einfach das ausliest, was Dich interessiert - in diesem Fall die X-, Y- und Z-Werte.
Grundregel Nr.1 dabei ist: baue Dir eine Struktur, die dem entspricht, was Du viele Male aus der Datei auslesen willst. Also hier ganz einfachstruct XYZ { double m_x, m_y, m_z; };Regel Nr. 2 füge eine Lesefunktion hinzu
#include <iostream> struct XYZ { friend std::istream& operator>>( std::istream& in, XYZ& xy ); double m_x, m_y, m_z; };Vorher solltest Du natürlich genau wissen, wie Deine Datei aufgebaut ist. Also auch die Teile, die nicht eingelesen werden sollen, müssen definiert sein. Ich unterstelle mal, dass die Zeichen 'X', 'Y' und 'Z' exklusiv sind und in keinem anderen Zusammenhang in der Datei auftauchen. Dann kann die Einlesefunktion etwa so aussehen
std::istream& operator>>( std::istream& in, XYZ& xy ) { typedef std::istream::traits_type traits_type; if( in.ignore( 9999, traits_type::to_int_type( 'X' ) ) ) { XYZ tmp; char cy, cz; if( (in >> tmp.m_x >> cy >> tmp.m_y >> cz >> tmp.m_z).ignore( 9999, traits_type::to_int_type( '\n' ) ) ) { if( cy == 'Y' && cz == 'Z' ) { // alles korrekt gelesen xy = tmp; // Input übernehmen } else in.setstate( std::ios_base::failbit ); // Fehler es folgt kein 'Y' oder 'Z' } } return in; }Und der Rest geht jetzt so, wie das Einlesen einzelner Integerwerte
#include <fstream> #include <vector> #include <iterator> int main() { using namespace std; ifstream file("input.txt"); std::vector< XYZ > xyz( (istream_iterator< XYZ >( file )), istream_iterator< XYZ >() ); // 'xyz' ist mit den Werten aus der Datei gefüllt return 0; }Oder auch - wenn Du das istream_iterator etwas kryptisch findest
#include <fstream> int main() { using namespace std; ifstream file("input.txt"); for( XYZ xyz; file >> xyz; ) { // hier das xyz-Objekt weiterverarbeiten } return 0; }Gruß
Werner
-
Wenn die Datei nur aus der Struktur besteht, kannst du die Datein aber auch als Binärdateien speichern. Allerdings kannst du sie dann nur noch mit einem Hexeditor bearbeiten (die gespeicherte Datei)
struct asd { int x; int y; int z; };asd testwerte[100]; for(int i=0; i<=100;++i) //Struktur mit Werten füllen { testwerte[i].x = 1; testwerte[i].y = 1; testwerte[i].z = 1; } fstream datei; //Struktur Array auf die Festplatte schreiben datei.open("test.dat", ios::binary | ios::out); datei.write(reinterpret_cast<char*>(testwerte),sizeof(asd)*100); datei.close(); memset(testwerte,0,sizeof(asd)*100); //Nur zur Demonstration erforderlich //Strukturarray wiedereinlesen datei.open("test.dat",ios::binary | ios::in); datei.read(reinterpret_cast<char*>(testwerte),sizeof(asd)*100); for(int i=0; i<=100;++i) { //Daten verarbeiten cout << testwerte[i].x << endl; cout << testwerte[i].y << endl; cout << testwerte[i].z << endl; }Es fällt im Code oben natürlich noch die Fehlerbehandlung und man kann damit nur
Arrays einlesen, wenn man deren Länge kennt. Doch natürlich kann man dieses Problem umgehen, wenn man am Anfang der Datei die Länge des Array speichert.
-
Werner Salomon schrieb:
...
struct XYZ { friend std::istream& operator>>( std::istream& in, XYZ& xy ); double m_x, m_y, m_z; }; ... std::istream& operator>>( std::istream& in, XYZ& xy ) { typedef std::istream::traits_type traits_type; ... std::vector< XYZ > xyz( (istream_iterator< XYZ >( file )), istream_iterator< XYZ >() );...
Gruß
WernerAaaah !

Sehr elegant ! Das gefällt mir.Danke,
Simon2.
flammenvogel schrieb:
Wenn die Datei nur aus der Struktur besteht, kannst du die Datein aber auch als Binärdateien speichern. ...
Der Vorschlag wird ihm wohl nicht viel helfen:
samo schrieb:
...
P.S.: Die einzulesende Datei kann ich nicht aendern, die bekomme ich so von einem anderen Programm das ich nicht beinflussen kannGruß,
Simon2.
-
@Simon2: Ups, das hab ich wohl überlesen. Vielleicht sollte ich das nächste mal etwas genauer hinschauen.

-
flammenvogel schrieb:
@Simon2: Ups, das hab ich wohl überlesen. Vielleicht sollte ich das nächste mal etwas genauer hinschauen.

Macht ja nix ... passiert mir auch öfter.

Gruß,
Simon2.