while-Schleife terminiert nicht.



  • Hallo.
    Ich verzweifle gerade an einem wahrscheinlich recht einfachen Programm. Eine Zeichenkette soll durchlaufen werden und ein Teil davon (genauer gesagt das erste Wort)
    in einen anderen String kopiert werden.
    Allerdings wird die while-Schleife nicht beendet, obwohl ich sie mit mehreren,
    teilweise sogar überflüssigen Kontrollwerten versehen habe. Ich habe mit hilfe
    des Debuggers Schritt für Schritt die Schleife durchgesehen und sie stoppt nicht,
    sondern läuft weiter, was natürlich zu einem überlauf der C-Strings führt.
    Hier der gekürzte Code:

    #include <iostream>
    #include <string.h>
    #include <conio.h>
    
    #define MAX_COMMAND_LENGTH	50
    
    using namespace std;
    
    char szCurrentCommand[MAX_COMMAND_LENGTH];
    
    void EvaluateCommand(char* pszText);
    
    int main()
    {
    	EvaluateCommand("Test");
    	cout << szCurrentCommand << '\n';
    	_getch();
    	return 0;
    }
    
    void EvaluateCommand(char* pszText)
    {
    	int iIndex		 = 0;
    	int iIterator	  = 0;
    	char szTemp		= 'a';
    	char szCommand[MAX_COMMAND_LENGTH];
    
    	//Iterate from the first letter to the last one and save those letters to a buffer
    	while((szTemp != '\n')||(szTemp != ' ')||(szTemp != '\0')||(iIterator <	MAX_COMMAND_LENGTH)||(iIndex < strlen(pszText)))
    	{
    		szTemp = pszText[iIndex];
    		szCommand[iIterator] = pszText[iIndex];
    		iIterator++;
    		iIndex++;
    	}
    
    	szCommand[iIterator] = '\0';	//Zero-Terminate the Command-String
    
    	strncpy(szCurrentCommand, szCommand, sizeof(szCommand));
    }
    

    Ich bin mir eigentlich fast sicher, dass ich wieder einmal etwas nicht
    korrekt angewendet oder verstanden habe. Allerdings komme ich einfach nicht
    auf die Lösung und hoffe ihr könnt mir helfen.

    Gruß Honky



  • Für deine C-Version ist der Fehler, dass es bei der while-Abfrage && anstatt || sein muss.

    Für C++:

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    string EvaluateCommand(const string &str)
    {
    	return str.substr(0, str.find(' '));
    }
    
    int main()
    {
        cout << EvaluateCommand("Test") << '\n';
        return 0;
    }
    


  • Der erste Fehler, der mir auffaellt und der auch der groesste ist, dass du kein C++ sondern C mit cout programmiert hast.
    Warum dieses besch...eidene C-Stringgewusel, wenn dir std::string die Arbeit abinimmt?
    In welchem Buch hast du das gelernt?

    Was mir grad noch beim ueberfliegen stilistisch aufgefallen ist: Ungarische Notation ist allgemein verpoehnt, aber wenn man sie schon verwendet, dann richtig (sz steht fuer zeroterminated string, du benutzt es aber fuer ein einzelnes Char).

    Entscheide dich bitte: Willst du C oder C++ programmieren. Dann kann man dir auch besser helfen.



  • Ich weiß nicht. Mir gefallen C-Strings. Und die WinApi arbeitet ja auch konstant
    mit C-Strings. Oder nicht?



  • Wurstinator schrieb:

    string EvaluateCommand(const string &str)
    {
    	return str.substr(0, str.find(' '));
    }
    

    Ich hätte jetzt eher an das gedacht:

    string str = "Test";
    string copy;
    istringstream(str) >> copy; // Schön, dass es in C++11 mit einem Temporary funktioniert. :-)
    

    Aber was nun wirklich die effizienteste Methode ist, das erste Wort einer Zeichenkette zu extrahieren, keine Ahnung?


  • Mod

    Honky schrieb:

    Ich weiß nicht. Mir gefallen C-Strings.

    Das ist keine Frage des Geschmacks, sondern eine Frage der SPrache, die du benutzen möchtest. Ich behaupte auch mal, du kennst weder std::string noch C-Strings so richtig gut, wenn dir C-Strings gefallen 😉 .

    Und die WinApi arbeitet ja auch konstant
    mit C-Strings. Oder nicht?

    Ja, aber es ist ja nicht so, dass man in C++ am rohen Winapi-Interface rumfummeln würde und selbst wenn, kann man zur Not auch mit std::string aus C++ einen C-String erzeugen.

    Aber nochmal: Die Frage ist, welche Sprache du lernen möchtest, C oder C++. Im Moment lernst du (wahrscheinlich aus einer sehr schlechten Quelle) irgendwie beides so halb. Das wird nicht lange gut gehen. Du bist gerade an dem Punkt, an dem es das erste Mal krachen wird, danach wird's nur schlimmer.



  • Natürlich möchte ich C++ lernen. 😉 Und ich kenne mich auch ein wenig mit std::strings aus. Aber in vielen C++-Büchern werden ja auch C-Strings benutzt.
    Es ist klar das std::strings große Vorzüge aufweisen. Aber wenn dies stilistisch
    ein solch großes Verbrechen ist, dann werde ich mich in Zukunft an euren Rat halten
    und C++-Strings statt C-Strings verwenden. 😃


  • Mod

    Honky schrieb:

    Aber in vielen C++-Büchern werden ja auch C-Strings benutzt.

    Ich äußere mal Zweifel an der Qualität deiner Literatur. Dirk Louis? Jürgen Wolf? Galileo-Verlag?



  • Galileo Verlag 😞



  • Warum verwendest du ein #define als Konstante statt

    const
    

  • Mod

    IrgendeinName schrieb:

    Warum verwendest du ein #define als Konstante statt

    const
    

    Hat er schon erklärt:

    Honky schrieb:

    Galileo Verlag 😞



  • Das hab ich im Eifer des Gefechts einfach schnell als #define gemacht. Ich ändere
    es aber in meinem Programm noch ab.



  • SeppJ schrieb:

    IrgendeinName schrieb:

    Warum verwendest du ein #define als Konstante statt

    const
    

    Hat er schon erklärt:

    Honky schrieb:

    Galileo Verlag 😞

    LOL 😃
    Ja ok, ich habs verstanden. Ich werde mir einen besseren Stil aneignen. 😃



  • Juergen unser alter Schlawiner schreibt nicht explizit, dass Makros boese sind. Er zeigt nur Unterschiede zwischen Konstanten und (Skalar-Literal) Makros.



  • Honky schrieb:

    Ich werde mir einen besseren Stil aneignen. 😃

    Eigne Dir lieber ein gutes Buch an. In Sepps Signatur gibt es einen Link mit Buchempfehlungen.



  • Sone schrieb:

    (Skalar-Literal) Makros.

    Woher nimmst du nur die Wörter. 😃



  • Für das Separieren eines durch Whitespaces getrennten Teilstrings aus einem String nimmt man sscanf und einen Einzeiler wie

    if( 1==sscanf(" blafasel\t\n","%49s",chararray50) )
      puts(chararray50);
    else
      puts("EOF oder Lesefehler");
    

    Und der Ausgangsstring darf sogar const sein, bzw. implizit const als Stringliteral.



  • Wutz schrieb:

    Für das Separieren eines durch Whitespaces getrennten Teilstrings aus einem String nimmt man sscanf und einen Einzeiler wie

    if( 1==sscanf(" blafasel\t\n","%49s",chararray50) )
      puts(chararray50);
    else
      puts("EOF oder Lesefehler");
    

    Und der Ausgangsstring darf sogar const sein, bzw. implizit const als Stringliteral.

    tinnef.
    ich nehme an, das wort ist vorher nicht bekannt. dann nimmt man funktionen wie find, copy, etc. aus der string-bibliothek.
    http://www.cplusplus.com/reference/string/string/



  • Oder direkt boost::split



  • Wutz schrieb:

    Für das Separieren eines durch Whitespaces getrennten Teilstrings aus einem String nimmt man sscanf und einen Einzeiler wie

    if( 1==sscanf(" blafasel\t\n","%49s",chararray50) )
      puts(chararray50);
    else
      puts("EOF oder Lesefehler");
    

    Und der Ausgangsstring darf sogar const sein, bzw. implizit const als Stringliteral.

    Sind wir im C-Forum? Geh bloss weg mit diesem Dreck... 👎

    std::string hw = "Hallo Welt!",
                erstesWort;
    
    std::istringstream(hw) >> erstesWort;
    

    Oder dein Beispiel (wenn ich es verstanden habe):

    std::string hw = " blafasel\t\n",
                erstesWort;
    
    std::istringstream(hw) >> std::ws >> erstesWort;
    

    @Eisflamme: Obiges ist einfacher und braucht kein boost :p

    Sorry fuer die ganzen edits.


Anmelden zum Antworten