schleife endet nicht



  • ich bekomme die Schleife nicht so weit das sie sich erfolgreich endet, sie wenn einen fehler ausgibt also nicht mehr findet
    bool cgi::output()
    {

    if (anfrage())
    {

    input cgiinput;

    do
    {
    f_start = query.find("+", start);

    f_start += 1;

    v_start = query.find("=", f_start);

    f_end = v_start;

    f_end -= 1;

    v_start += 1;

    f_size = f_end - f_start;

    v_end = query.find("+",f_start);
    v_end -= 1;
    v_size = v_end - v_start;

    cgiinput.formname += query.substr(f_start, f_size);
    cgiinput.value += query.substr(v_start, v_size);
    start += v_end;
    }

    while(v_end == string::npos);

    cout << cgiinput.formname << "<p></p>" << endl;
    cout << cgiinput.value << "<p></p>" << endl;

    return true;
    }



  • Der Code wäre angenehmer zu lesen, wenn du ihn in

    und
    

    -Tags einschließen würdest..
    Zu deiner "Frage":
    v_end==string::npos dürfte eigentlich nie wahr werden, da v_end ja string::find - 1 ist, im Fall des Nicht-Findens also npos-1.. Hast du evtl noch ein paar mehr Infos? Bist du schon mit dem Debugger durchgegangen?



  • stimmt danke, aber wenn ich zb vsize bricht die schleife zu früh ab

    bool cgi::output() 
    { 
    
    if (anfrage()) 
    {
    
    input cgiinput;
    
    do
    {
    f_start = query.find("?", start);
    
    if (f_start == string::npos)
    {
    f_start = query.find("&", start);
    };
    
    f_start += 2;
    f_end = query.find("=", f_start);
    f_end -=1;
    
    f_size = f_end - f_start;
    
    v_start = query.find("=", f_start);
    v_start += 1;
    
    v_end = query.find("&",f_start);
    
    if(v_end == string::npos)
    {
    v_end = query.find_last_of(v_start);
    };
    
    v_size = v_end - v_start;
    
    cgiinput.formname +=(query.substr(f_start, f_size));
    cgiinput.value += (query.substr(v_start, v_size));
    start += f_start;
    }
    
    while( v_size == string::npos);
    
    cout << cgiinput.formname << "<p></p>" << endl;
    cout << cgiinput.value << "<p></p>" << endl;
    
    return true;
    }
    
    else 
    return false; 
    };
    


  • Warum machst du es nicht leser-freundlich:

    bool found = false;
    do
    {
        ... = query.find( ... );
        if ( ... == string::npos )
            found = true;
    } while ( ! found );
    

    ?



  • habe es versucht leser freundlicher zu gestallten leider funzt es immer noch nicht, schleife scheint endlos weiter zu laufen program läuft nicht weiter:

    if (anfrage()) 
    {
    
    input cgiinput;
    
    cgiformat = false; 
    
    do
    {
    
    	f_start = query.find("?", start);
    
    		if (f_start == string::npos)
    		{
    			f_start = query.find("&", start);
    		}
    
    	f_start += 2;
    
    	f_end = query.find("=", f_start);
    	f_size = f_end - f_start;
    
    	v_start = query.find("=", f_start);
    	v_start += 1;
    	v_end = query.find("&",f_start);
    
    		if(v_end == string::npos)
    		{
    		v_end = query.length();
    		cgiformat = true;
    		}
    
    	v_size = v_end - v_start;
    
    	cgiinput.formname +=(query.substr(f_start, f_size));
    	cgiinput.value += (query.substr(v_start, v_size));
    	start += f_start;
    
    }
    
    while( cgiformat == true );
    
    	cout << cgiinput.formname << "<p></p>" << endl;
    	cout << cgiinput.value << "<p></p>" << endl;
    
    return true;
    }
    
    else 
    return false; 
    };
    

    header

    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std; 
    
    class cgi 
    {
    private:
    string::size_type start;
    
    string::size_type f_start;
    string::size_type f_end;
    string::size_type f_size;
    
    string::size_type v_start;
    string::size_type v_end;
    string::size_type v_size;
    
    bool cgiformat;
    
    public: 
    string query;
    bool anfrage(); 
    bool output();
    };
    
    struct input
    {
    string formname;
    string value;
    };
    
    class htmlform
    {
    private:
    
    public:
    void starthtml(string sitename);
    void endhtml();
    void startform(string methodform, string name);
    void endform();
    void input( string submitlabel, string type);
    void formselect(string formselectname, string formselectinput);
    };
    
    class htmllayer
    {
    private:
    
    public:
    void createlayer(string layerid);
    void endlayer();
    };
    


  • if (anfrage())
    {
        // viel Code
    }
    else
        return false;
    
    // =>
    if ( ! anfrage() )
        return false;
    
    // viel Code
    
    f_start = query.find("?", start);
    if (f_start == string::npos)
        f_start = query.find("&", start);
    

    Ist fehleranträchtig, was ist, wenn auch kein "&" gefunden wird?

    3. Dein Einrück-Stil ist sehr unkonventionell 😉

    4. Was ist das denn?: while( v_end == true );



  • programm endet debugger jetzt normal gibt ersten datensatz aus mehr aber auch nicht

    source code
    http://rs177tl2.rapidshare.com/files/64210338/tuxhtml.tar.gz



  • Was soll der Code überhaupt machen?



  • cgi ausgabe formatieren und die daten in einem struct speichern damit ich sie im program nacher weiterverarbeiten kann.



  • Beziehe mich auf Tuxists Beitrag vom 21.10.2007 21:56:58
    Klassische Endlosschleife in Zeile 37

    while( cgiformat == true );
    


  • Kenner der Schleifen schrieb:

    Beziehe mich auf Tuxists Beitrag vom 21.10.2007 21:56:58
    Klassische Endlosschleife in Zeile 37

    while( cgiformat == true );
    

    Hast du überhaupt den kompletten Quelltext gelesen? Das ist der Abschluß einer recht umfangreichen do-while-Schleife (und im Inneren der Schleife wird cgiformat auch gesetzt) 😉

    @tuxist: Schonmal das Programm durch den Debugger gejagt? Auf Anhieb fällt mir nur auf, daß dein Abbruchkriterium verkehrt herum gesetzt ist - die Schleife läuft weiter, wenn die angegebene Bedingung erfüllt ist - und dank der Initialisierung mit 'cgiinput=false' ist das schon nach dem ersten Durchlauf nicht der Fall.



  • Bei einer solchen Formatierung ist es kein Wunder, dass man die Übersicht verliert. Es sah beim überfliegen aus, als wär es eine while-Schleife

    do
    {
    //viele Zeilen
    //zum überfliegen
    }
    
    while(...);
    


  • der fehler scheint hir zu liegen:

    f_start = query.find("?", start);
    
    		if (f_start == string::npos)
    		{
    			f_start = query.find("&", start);
    
    		}
    	else
    	cgiformat = true; //wenn ich dieses weg lasse endet die schleife endloss
    

    dieses scheint nie true zu werden, müsste doch aber eigentlich wenn er kein ? finder oder habe ich hier einen logic fehler.



  • Ich habe mal angefangen, deinen Code aufzuräumen... (ich hatte Langeweile).
    Da ist mir eine entscheidene Frage in den Sinn gekommen, die mich zu dem Schluss bringen, dass du die gesamte Funktion/Methode mal überdenken solltest (siehe Kommentare).

    bool cgi::output()
    	{
    		if( !anfrage() ) return false;
    			// Bedingung umgekehrt hierdurch wird die Methode direkt
    			//	mit false verlassen, wenn die Abfrage nicht
    			//	erfolgreich war. Folge: Code wird übersichtlicher.
    
    		input cgiinput;
    
    		do {
    
    			// Sucht die erste Zeichenkette, welche auf "?" passt
    			//	(ab start): Die Position in f_start
    			f_start = query.find("?", start);
    
    			// Kann die Zeichenkette nicht gefunden werden, so wird
    			//	nach der Zeichenkette "&" gesucht.
    			if (f_start == string::npos) {
    				f_start = query.find("&", start);
    			};
    			// ** Anmerkung 1: **
    			// Hier erfolgt jedoch keine Prüfung mehr, ob ein "&"
    			//	auch tatsächlich gefunden wurde. Ist das so
    			//	gewünscht?
    
    			f_start += 2;
    			// f_start soll wohl hier auf den Anfang der
    			//	GET-Variable gesetzt werden, ob f_start den
    			//  richtigen Wert aufweist (Anmerkung 1) ist fraglich.
    
    			// Auf das Prüfen einer GET-Variable schließe ich,
    			//	da die Zeichen ? und & geprüft werden sollen.
    			f_end = query.find("=", f_start);
    			f_end -=1;
    
    			f_size = f_end - f_start;
    
    			v_start = query.find("=", f_start);
    			v_start += 1;
    
    			v_end = query.find("&",f_start);
    
    			if(v_end == string::npos) {
    				v_end = query.find_last_of(v_start);
    			};
    
    			v_size = v_end - v_start;
    
    			cgiinput.formname +=(query.substr(f_start, f_size));
    			cgiinput.value += (query.substr(v_start, v_size));
    			start += f_start;
    
    		} while( v_size == string::npos);
    
    		cout << cgiinput.formname << "<p></p>" << endl;
    		cout << cgiinput.value << "<p></p>" << endl;
    
    		return true;
    
    	}
    

    Korrigiere mich, wenn ich falsch liegen sollte.

    Grüße...

    Heiko



  • Ich sehe ja ein das die Schleife unübersichtlich ist, aber ein anderer Lösungsweg ist mir nicht eingefallen und den query string in ein struct zu bekommen mit allen in dem query string enthaltenen werten.

    dar ich formname und value getrennt in dem struct haben möchte.

    Das problem ist mehrere query werte in das struct zu bekommen.



  • habe noch versucht auf anmerkung eins enzugehen, leider ohne erfolg

    if( !anfrage() ) return false; 
    {
    
    	input cgiinput; // struct wird initalisiert
    
    	cgiformat = false; //bool wert wird gesetzt
    	start = 1;
    
    do { 
    
                 // Sucht die erste Zeichenkette, welche auf "?" passt 
                 //    (ab start): Die Position in f_start 
    	     if(start == 1)
    		{
    		f_start = query.find("?");
    		}
                 // Kann die Zeichenkette nicht gefunden werden, so wird 
                 //    nach der Zeichenkette "&" gesucht. 
                 else 
    		{
    
    		f_start = query.find("&", start);
    
    		if(f_start == string::npos)
    		{
    		cout << "error" << endl;
    		break;
    		}
    
    		};
    
                 // ** Anmerkung 1: ** 
                 // Hier erfolgt jedoch keine Prüfung mehr, ob ein "&" 
                 //    auch tatsächlich gefunden wurde. Ist das so 
                 //    gewünscht? 
    		cout << start << endl;
    		cout << f_start << endl;
                 f_start += 2;
                 // f_start soll wohl hier auf den Anfang der 
                 //    GET-Variable gesetzt werden, ob f_start den 
                 //  richtigen Wert aufweist (Anmerkung 1) ist fraglich. 
    
                 // Auf das Prüfen einer GET-Variable schließe ich, 
                 //    da die Zeichen ? und & geprüft werden sollen. 
                 f_end = query.find("=", f_start); 
                 f_end -=1; 
    
                 f_size = f_end - f_start; 
    
                 v_start = query.find("=", f_start); 
                 v_start += 1; 
    
                 v_end = query.find("&",f_start); 
    
                 if(v_end == string::npos) { 
                     v_end = query.find_last_of(v_start);
    		 cgiformat = true;
                 }; 
    
                 v_size = v_end - v_start;
    
                 cgiinput.formname +=(query.substr(f_start, f_size)); 
                 cgiinput.value += (query.substr(v_start, v_size)); 
                 start += f_start;
    	     cout << start << endl;
    
            } while( cgiformat == true);
    
             cout << cgiinput.formname << "<p></p>" << endl; 
             cout << cgiinput.value << "<p></p>" << endl; 
    
             return true; 
    
         } 
    
    };
    


  • Ich gehe mal weiterhin davon aus, dass du einen HTTP-Request auswerten willst.

    Ein minimal HTTP-Request sieht wie folgt aus:

    GET /foobar.cgi?varname1=varvalue1&foo=bar&bar=fuzzy&lonely HTTP/1.1
    Host: www.dubhost.nop
    

    Du solltest das Auswerten dieser Zeichenkette nicht in der Klasse vornehmen, sondern dafür einfach eine Funktion schreiben, welche die einzelnen Variablen in einem Container (std::map ist sinnvoll) zurück gibt (so kann man diese auch später für weitere CGI-Programme verwenden).

    (Dadurch, dass du einfache "Arbeitsvariablen" als Klassenmember definierst hast du schon fast so etwas wie globale Variablen nur eben auf Klassenebene. Das ist sicherlich kein Vorteil für die Übersichtlichkeit.)

    Arbeitsschritte:

    1. Herauslösen der Zeichenkette /foobar.cgi?varname1=varvalue1&foo=bar&bar=fuzzy&lonely aus dem Request
    (Tipp: Leerzeichen!)

    2. Herauslösen der Zeichenkette, welche die Variablen enthält (varname1=varvalue1&foo=bar&bar=fuzzy&lonely)

    3. Aufteilen der Zeichenkette in die einzelnen Variablen:
    varname1=varvalue1 .. foo=bar .. bar=fuzzy .. lonely
    (Tipp: std::vector zum zwischenspeichern)

    4. Jeden einzelnen Eintrag im std::vector nochmals in ein Zeichenkettenpaar (Variablenname, Inhalt) aufteilen (Achtung: Es muss kein Inhalt und damit kein '=' vorhanden sein!) und dieses Paar dann in der std::map ablegen.

    5. Kopie der std::map zurückgegeben.

    Hinweis: Jeden dieser Arbeitsschritte sollte man in einer eigenen Funktion definieren und lediglich diese Aufrufen (macht die Sache wieder übersichtlicher).

    Worauf du in Zukunft achten solltest ist vor allem, dass du deinen Code sinnvoll einrückst, Lesbarkeit und Übersichtlichkeit ist das Wichtigste! [1]

    Kommentiere deinen Code. Ein verhältnis von 2:1 Kommentar zu Code ist schon ganz brauchbar. Kommentiere nicht die einzelnen Zeilen, sondern im Vorfeld, was ein gewisser Codeabschnitt leisten soll (bevor du den Code geschrieben hast). Schreibe auch mögliche Fehlerursachen auf. Das hilft, die Gedanke im Kopf zu sortieren und Fehler meistens schon zu finden, bevor du eine Zeile Code geschrieben hast.

    Refaktorisiere: Wird eine Funktion zu groß (und damit unübersichtlich) teile diese in mehrere Funktionen auf. Das hat den Vorteil, dass du diese Funktionen später einzelnen Testen kannst.

    Versuche jetzt aber bitte nicht, deinen vorhandenen Code zu entrümpeln. Ich empfehle eine Warmsanierung 😉

    Grüße...

    Heiko
    ---
    [1]: Schau dir mal die Codebeispiele hier im Forum an, wie diese formatiert sind. Du bist zwar im Grunde frei in der Entscheidung, wie du deinen Code formatierst, aber an gewisse Regeln sollte man sich halten damit andere den Code auch lesen können 😉

    (Ja, das ist zu lang für eine Fußnote...)


Anmelden zum Antworten