zahlen aus einem string lesen
-
ich dachte der funktioniert nicht.
-
darman96 schrieb:
ich dachte der funktioniert nicht.
Mach aus
return in >> char() >> out.x >> out.y >> out.z;
ein
char c; return in >> c >> out.x >> out.y >> out.z;
Du hast doch sicher schon mit std::cin gearbeitet? Dann sollte die Vorgehensweise recht gut zu verstehen sein, vorrausgesetzt man weiß was Operatorenüberladung macht.
-
das mit der operatorüberladung weiß ich leider nicht
-
Hallo darman96,
um es kurz zu machen: Du hast eine Datei und Du möchtest Koordinaten aus dieser Datei in Deinem Programm einlesen.
Damit wir Dir wirksam helfen können, müssen wir zwei Dinge wissen.
1.) wie sieht diese Datei aus? Hat das Dateiformat einen Namen? Kannst Du vielleicht ein kleines Beispiel hier posten.
2.) Was hast Du nach dem Einlesen mir den Koordinaten vor, also in welcher Form möchtest Du darauf zugreifen?Die (Ideal)Lösung sieht so aus: Du hast eine Klasse oder Struktur (oder mehrere), mit der Du Deine Aufgabe bestmöglich lösen kannst, und zwar unabhängig davon, wie diese Koordinaten - oder was da auch immer noch drin steht - in der Datei untergebracht sind. Und genau für diese Klasse oder Struktur schreibt man dann eine Funktion, die diese aus der Datei direkt ausliest. Letzteres ist dann die operator-Überladung.
.. versuche mal, meine beiden Fragen oben zu beantworten.
Gruß
Werner
-
- Also es handelt sich um .obj dateien. Die sind so aufgebaut
# Blender v2.61 (sub 0) OBJ File: '' # www.blender.org mtllib block.mtl o Cube v 1.000000 -1.000000 -1.000000 v 1.000000 -1.000000 1.000000 v -1.000000 -1.000000 1.000000 v -1.000000 -1.000000 -1.000000 v 1.000000 1.000000 -0.999999 v 0.999999 1.000000 1.000001 v -1.000000 1.000000 1.000000 v -1.000000 1.000000 -1.000000 usemtl Material s off f 1 2 3 4 f 5 8 7 6 f 1 5 6 2 f 2 6 7 3 f 3 7 8 4 f 5 1 4 8
und ich will nur die zeilen mit den v´s . das hab ich auch schon hinbekommen, was jetzt noch fehlt ist die Zahlen rauszufiltern.
- nach dem Einlesen möchte ich die in einer Struktur (VERTEX) speichern. die struktur hab ich auch schon es geht nur darum die zahlen zu trennen.
-
Die Lösung wurde von seldon schon genannt. Hast du damit noch Schwierigkeiten? Zeig mal deinen Code, den du bis jetzt hast.
-
So hier der Code:
/* base.cpp */ #include "base.h" #include <iostream> #include <fstream> #include <sstream> using namespace std; ModelLoader::ModelLoader() { } bool ModelLoader::LoadObjFile(string path) { ReadFile(path); return true; } bool ModelLoader::ReadFile(string path) { // variables fstream stream; fstream stream_count; string content; VERTEX vertex; int x = 0; // opens file stream.open(path); // if file is open -> continue if (! stream.is_open()) { return false; } // opens file stream_count.open(path); // if file is open -> continue if (! stream_count.is_open()) { return false; } while(! stream_count.eof()) { getline(stream_count, content); if(content[0] == 'v') { x++; } } // Arraygröße festlegen mdl.setVertexCount(x); x = 0; while(! stream.eof()) { getline(stream, content); if(content[0] == 'v') { mdl.addVertex(x, GetVertex(content)); x++; } } return true; } VERTEX ModelLoader::GetVertex(string line) { VERTEX vertex; int x = 0; string coord = ""; stringstream stream; for (int i = 0; i < line.length()-1; i++) { if(line[i] == ' ') { switch(x) { case 1: stream << coord; stream >> vertex.X; coord = ""; break; case 2: stream << coord; stream >> vertex.Y; coord = ""; break; case 3: stream << coord; stream >> vertex.Z; coord = ""; break; } x++; } else if ( x != 0 ) { coord = coord + line[i]; } } return vertex; }
Edit: hier ist auch schon ein Versuch drin die Zahlen zu trennen das hat aber nicht geklappt.
-
Liest du die Antworten, die du bekommst? Das hat ja wohl überhaupt nicht mit dem zu tun, was dir gesagt wurde. Tatsächlich ist das Lesen sogar voller Fehler, kein Wunder, dass das nicht funktioniert. Erwartest du, dass jemand für dich deine Fehler in deinem Programm ausbessert?
-
Nein ich hatte den Code hier auch schon bevor ich den thread eröffnet habe.
Nur da mein Code nicht funktionierte wollte ich wissen wie man das vllt anders lösen könnte.
-
ok es funktioniert jetzt mit dem Code von seldon.
aber was macht der '>>' operator in diesem fall genau?
ich möchte das programm ja auch verstehen
-
darman96 schrieb:
- Also es handelt sich um .obj dateien.
damit ist die erste Frage eindeutig beantwortet. Das obj-Format von Wavefront ist bekannt.
darman96 schrieb:
- nach dem Einlesen möchte ich die in einer Struktur (VERTEX) speichern.
das ist nicht viel - aus Deinem Code kann ich folgern, dass VERTEX so aussieht:
struct VERTEX { double X, Y, Z; };
Wenn Du nur die vertices brauchst, so überlese alle Zeilen, die nicht mit einem v beginnen. Anschließend liest Du dann ein VERTEX ein und das macht man solange es keinen Lesefehler gibt - und den gibt es spätestens, wenn EOF erreicht wird.
#include <fstream> #include <limits> #include <iostream> #include <string> #include <vector> struct VERTEX { double X, Y, Z; }; // -- das ist die operator-Überladung für VERTEX // und hier werden die Zahlen getrennt (eingelesen) std::istream& operator>>( std::istream& in, VERTEX& v ) { return in >> v.X >> v.Y >> v.Z; } // -- überlese alles bis "v" am Zeilenanfang std::istream& skip_until_v( std::istream& in ) { for( std::string v; in >> v && v != "v"; ) in.ignore( std::numeric_limits< std::streamsize >::max(), '\n' ); return in; } std::vector< VERTEX > read_vertex( const char* filename ) { using namespace std; vector< VERTEX > vv; ifstream datei(filename); if( !datei.is_open() ) { cerr << "konnte Datei " << filename << " nicht oeffnen" << endl; return vector< VERTEX >(); } for( VERTEX vertex; datei >> skip_until_v >> vertex; ) vv.push_back( vertex ); return vv; } int main() { using namespace std; vector< VERTEX > vertices = read_vertex("wavefront.obj"); cout << "es wurden " << vertices.size() << " vertices gelesen" << endl; // ... die Koordinaten sind in der Struktur VERTEX gespeichert cin.get(); return 0; }
Das getrennte Einlesen der Zahlen in Zeile 16 funktioniert nicht anders als es Ethon bzw. seldon schon skizziert haben. Mehr dazu findest Du unter extraction operator des std::istream. Falls Du sonst noch Fragen zum Code hast, so stelle sie bitte.
Gruß
Werner
-
Der Ein-/Ausgabeoperator funktioniert grundsätzlich nicht bei Klassen,
da ein Objekt einer Klasse mehrere Eigenschaften haben kann.Z.B.
class student { public: string Alter; string Name; };
Wenn man nun ein Objekt der Klasse anlegt, z.B.: student s und versucht, mittels
cin>>s oder cin>>"50">>"Meyer" Daten einzugeben, funktioniert das logischerweise nicht, da der Compiler nicht weiß, ob nun das Alter oder der Name eingegeben werden soll.
Man kann dem Compiler durch eine Überladung von ">>" aber sagen, er soll bei einer Eingabe von cin>>"50">>"Meyer" das Alter mit 50 speichern und den Namen mit "Meyer".
-
@redrew99: Deine Begründung gefällt mir nicht. es liegt nicht da dran, dass der Kontext nicht eindeutig wäre. Es liegt da dran, dass schlichtweg keine solche Funktion existiert, wenn man sie nicht selber schreibt.
Die Operatoren kann man als ganz normale Funktionen auffassen, die optional mit einer etwas anderen Syntax aufgerufen werden können. Man kann nämlich auch
bar.operator>>(foo
) schreiben stattbar >> foo
und das ist äquivalent. Und der Knackpunkt hier ist, dass es schlicht keine Funktionoperator>>(std::istream&, student &)
gibt. Daher muss man die Funktion selber schreiben.
-
ok es funktioniert jetzt.
danke an alle für die Antworten.@Werner: danke auch für den link zum wiki eintrag von obj dateien jetzt weiß ich auch wo ich sehe welche vertices ich zu nem Face verbinden muss.
Gruß darman96
-
Dieser Beitrag wurde gelöscht!