Problem mit der Stringfind funktion!



  • Hallo,

    ich bin gerade mal wieder am Programmieren und hab jetzt ein ziemlich triviales Problem aber trotzdem komm ich grad von selbst nicht drauf.

    Ich hab 4 Klassen. Polygonline, Point, Circle, Rectangle... Jede dieser Klassen hat einen Konstruktor welcher einen String mit Koordinaten nimmt und ihn auswertet. So bekommt zum Beispiel die Klasse Point einen solchen string: (x, y). Der Konstruktor wertet ihn aus und initialisert dann x und y. Funktioniert auch alles.

    Nun hab ich aber eine Oberklasse namens Drawingobjekt von welcher die anderen abgeleitet sind. Diese Drawingobject hat auch eine virtuelle print funktion, naja tut eigentlich nix zur sache.

    Also lange rede kurzer sinn, mein Problem ist folgendes.

    Ich will nun anhand des String welchen der Benutzer eingibt erkennen für welche Klasse dieser vorgesehen ist.

    Point bekommt: (x, y)
    Circle bekommt: <(x, y), radius>
    Polygonline: {(x, y) - (x, y) -...}

    Also wollte ich per String Find funktion das ermitteln. Wenn "<" gefunden wird dann für Circle, bei erfolgreichem finden von "-" bekommt es Polygonline.

    Jedoch klappt das nicht wenn ich "(", "<" oder sowas suchen will. Entweder bekomm ich als wert 0 oder nen Debug fehler??

    Wo könnte der Fehler liegen?

    #include <iostream>
    #include <string>
    #include <sstream>
    #include "class_DrawingObject.hpp"
    #include "class_OneDimObject.hpp"
    #include "class_point.hpp"
    #include "class_rectangle.hpp"
    #include "class_circle.hpp"
    #include "class_Polygonline.hpp"
    #include "global_var.hpp"
    
    using namespace std;
    
    int main()
    {
    DrawingObject * objects[20];
    	int anzahl = 0;
    	string str1;
    
    	Point p1, p2;
    
    	cout << "Wieviele Objekte wollen Sie einlesen?" << endl;
    	cout << "Anzahl: ";
    	cin >> anzahl;
    	fflush(stdin);
    
    	/*cout << "Was fuer ein Objekt moechten Sie einlesen? 0 > Point; 1 > Circle; 2 > Polygonline; 3 > Rectangle: ";
    
    	cin >> objwahl;
    	fflush(stdin);*/
    
    	// Objekte einlesen
    
    		for(int i=0; i<anzahl; i++)
    		{
    			cout << "Bitte Objektkoordinaten eingeben: ";
    			getline(cin, str1);
    			fflush(stdin);
    
    			//cout << endl << endl << str1 << endl << endl;
    			//cout << str1.find('<');
    			cout << endl << str1.find("(");
    
    			if((str1.find("\(")!=string::npos)) //&& str1.find(">"))!=NULL)
    				objects[i] = new Point(str1);
    		}
    return 0;
    }
    

    Viele Grüße mazeli



  • Also als erstes fällt mir auf, dass du in Zeile 18 einen Fehler hast: du hast ein Array mit Größe 20 auf DrawingObject Pointer.
    Deswegen wird dir die Zuweisung in Zeile 47 um die Ohren fliegen.

    Desweiteren frage ich mich, warum du in Zeile 46 ein Backslash vor der Klammer hast?

    Ach und in Zeile 39 kannst du statt getline() auch einfach "cin >> str1;" schreiben.



  • hmm also der backslash soll da wirklich nicht sein 🙂

    cin bricht aber beim auftreten von whitespaces ab, also beim ersten leerzeichen



  • Oh ja, stimmt. Sorry für diesen dummen Tip.
    Läuft es denn wenn du Zeile 18 und 46 verbesserst?



  • ich weiß allerdings nicht was falsch ist

    wenn ich es so schreibe funktioniert es, also wenn ich die Koordinaten über ein menü eingebe ohne das dass programm automatisch erkennt was es ist.

    cout << "Kreiskoordinaten eingeben, Format ist <(x1, y1), radius>: ";
    				getline(cin, str1);
    				fflush(stdin);
    				objects[i] = new Circle(str1);
    


  • Also ich weiß nicht was du hast, habe den Code so kompiliert und es geht einwandfrei:

    int main()
    {
        int anzahl = 0;
        string str1;
    
        cout << "Wieviele Objekte wollen Sie einlesen?" << endl;
        cout << "Anzahl: ";
        cin >> anzahl;
        fflush(stdin);
    
        for(int i=0; i<anzahl; i++)
        {
            cout << "Bitte Objektkoordinaten eingeben: ";
            getline(cin, str1);
            fflush(stdin);
    
            if(str1.find('(') != string::npos)
                cout << "found (" << endl;
        }
    
        return 0;
    }
    

    Dieser Code macht genau das was du willst...



  • Für solche "String-Parser"-Aufgaben eigenen sich doch Reguläre Ausdrücke. Oder stehe ich jetzt daneben?



  • Tobias W schrieb:

    Also ich weiß nicht was du hast, habe den Code so kompiliert und es geht einwandfrei:

    int main()
    {
        int anzahl = 0;
        string str1;
    
        cout << "Wieviele Objekte wollen Sie einlesen?" << endl;
        cout << "Anzahl: ";
        cin >> anzahl;
        fflush(stdin);
    
        for(int i=0; i<anzahl; i++)
        {
            cout << "Bitte Objektkoordinaten eingeben: ";
            getline(cin, str1);
            fflush(stdin);
    
            if(str1.find('(') != string::npos)
                cout << "found (" << endl;
        }
    
        return 0;
    }
    

    Dieser Code macht genau das was du willst...

    Danke! Ich hatte nen fatalen Denkfehler...naja war ja auch schon abends gestern 🙂

    Danke nochmal 🙂



  • Man ist das nen Murks:

    cin >> anzahl;
    fflush(stdin);
    

    undefiniertes Verhalten ...

    #include <iostream>
    #include <vector>
    #include <limits>
    
    std::istream& clear_stream(std::istream& in)
    { in.clear(); in.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); return in; }
    
    int main()
    {
        std::size_t size(0);
        while (!(clear_stream(std::cin) >> size))
            std::cout << "Wie viele Objekte beabsichtigen Sie einzulesen? ";
    
        std::vector<DrawingObject*> objects(size);
    
        for (std::size_t i(0); i < size; ++i)
        {
            std::cout << i << ". Objektk:\n\tKoordinaten: ";
            std::string str_input;
            std::getline(std::cin, str_input);
    
            if (str_1ine.find("<(") != std::string::npos && str_line.find(">") != std::string::npos)
                objects[i] = new circle(str_line);
            else if (/* ... Line ... */)
            else if (/* ... Point ... */)
        }
        for (std::size_t i(0); i < size; ++i) delete objects[i];
    }
    

    ... wobei du bei dem einlesen natürlich den Punkt als letztes einlesen solltest, da auch die anderen Objekte das Schema von diesem aufweisen.

    Aja das Klassendesign ist miserabel 😛
    Dann könntest du evtl. mal einfach operator>> überladen usw. würde das ganze viel eleganter machen ...


Anmelden zum Antworten