Problem mit Stringtransformation



  • guten tag erstmal,

    benötige dringend eine 2te/3te/4te meinung, da ich seit tagen festsitz und
    mittlerweile echt auf dem schlauch steh,
    weil ich nicht erkennen kann wo das Problem liegen könnte.

    Die aufgabe ist einen eingegebenen satz so zu ändern das er Wort für Wort umgedreht wird und dann ausgegeben
    Bsp.ein hund spielt im garten --> nie dnuh tleips mi netrag

    habe dazu folgenden code geschrieben:

    #include<iostream>
    #include<string>
    #include<cstddef>
    using namespace std;
    
    int main()
    {
    	size_t j=0,k=0;
    	string satz,invert;
    	cout<<"Geben sie den zu Ändernden Satz in die Konsole ein"<<endl;
    	getline(cin,satz);
    	invert=satz;
    	for(size_t i=0;i<satz.size();i++)
    	{
    		if(satz[i]==' '||i==satz.size()-1)					//durchsuchen des strings auf ende eines wortes(satz[i-1]führt zu abbruch)
    		{
    			for(k,j=i;k<=i&&j!=' ';j--,k++)					//j=i um ausgangs laufvariable zu erhalten.j liest das wort rückwärts k schreibt vorwärts in neuen string
    			{
    				if(satz[j]!=' ')							//zum erhalt der original leerzeichen, soll nur gedreht werden wenn kein " " vorhanden ist.
    				{
    				invert[k]=satz[j];			
    				}
    				else										//andernfalls soll ein " " geschrieben werden.
    				{invert[k]=' ';}
    			}
    		}
    	}
    	cout<<"Invert Satz:\n"<<invert<<endl;
    
    system("pause");
    }
    

    [code]

    mein Problem ist nur dass die Leerzeichen nicht an den stellen sitzen wo sie hinsollen,
    beziehungsweise nicht dort sind wo sie im original satz stehen.
    dabei scheint mir der lösungsweg logisch. vielleciht weiss jmd einen anderen oder sieht den Fehler in meiner konstruktion.
    vielen dank schonmal im vorraus



  • Die innere Schleife sieht auf jeden Fall seltsam aus - k wird nicht initialisiert und dann vergleichst du den Index j mit dem Leerzeichen anstelle des Zeichens an Stelle j.

    Ich hätte vermutlich mit find_first_of() die einzelnen Leerzeichen gesucht, den Eingabestring zerlegt, die einzelnen Teile invertiert und wieder zusammengebaut.



  • #include<iostream> 
    #include<string> 
    
    int main() 
    { 
      std::string Line;
      std::cout << "Geben Sie den zu ändernden Satz in ein:\n";
      std::getline(std::cin, Line);
      for(unsigned int Split = 0, Last = 0; Split < Line.lenght(); Split++)
      {
        if(Line[Split] == ' ')
        {
          std::string Part(Line.substr(Last, Split - Last));
          for(unsigned int Reverse = Last; Reverse < Split; Reverse++)
          {
            Line[Reverse] = Part[Last - Reverse];
          }
          Last = Split;
        }
      }
      std::cout << "\nResultat:\n";
      std::cout << Line;
      std::cin.get();
    }
    

    Ungetestet.

    MfG, EOutOfResources



  • Hmm mein Vorschlag wäre jetzt mittels istringstream und die Verwendung der STL:

    #include <iostream> 
    #include <string>
    #include <sstream>
    
    using namespace std; 
    
    int main() 
    { 
    	const char delimiter = ' ';
    
        cout<<"Geben Sie einen Satz ein: "; 
    	string eingabe;
    	getline(cin, eingabe);
    	istringstream str(eingabe);
    
        string invert, wort;
    	while(getline(str, wort, delimiter)){		//splitten der Wörter
    		std::reverse(wort.begin(),wort.end());	//drehen des Wortes
    		invert += wort + delimiter;				//Speichern für Ausgabe
    	}
    	cout << invert;
    }
    


  • erstmal vielen dank für die wirklich schnelle bearbeitung meines problems.
    @CStoll

    die innere schleife:

    for(k,j=i;k<=i&&j!=' ';j--,k++)
    

    k=0 :wurde lokal für die ganze main funktion initialisiert da der wert fortlaufend
    sein soll und nicht bei jedem schleifen aufruf wieder bei 0 beginnen darf da ja sonst das erste wort in invert jedesmal überschrieben wird oder?

    j=i :der maximale index des gefunden wortes

    ;k<=i :k, die laufvariable des invert strings, als abbruchbedingung an der oberen grenze des wortes.

    und j!=' ' :als untere begrenzung des wortes.
    es fehlt natürlich die untere begrenzung des ersten wortes,
    das hab ich allerdings getestet und macht keinen unterschied
    im ergebnis

    j--,k++ :naja rückwärts lesen, vorwärts schreiben ist ja soweit klar.

    @EOutOfResources
    n buchstaben dreher bei length. allerdings kommt auch dann ein
    "out of range" abbruch,kann aber nicht genau definieren wo er herkommt.
    die schweine quälen mich sowiso noch oft 😃

    @HighLigerBiMBam
    funktioniert auf jedenfall. wir haben allerdings bisher noch nicht mit der sstream bibliothek gearbeitet. hab mich nun aber ein wenig darüber schlau
    gemacht. sie ist ja mehr oder weniger für genau solche probleme da,
    "wörter" eines strings zu bearbeiten. daher hoff ich mal das das als lösung
    genügen sollte.

    vielen dank auf jedenfall schonmal.
    und falls noch jemandem eine lösung ohne <sstream> einfällt würde ich das
    rein interesse halber gerne hören/lesen 🙂
    ansonstn einen schönen samstag



  • rettich schrieb:

    und falls noch jemandem eine lösung ohne <sstream> einfällt würde ich das
    rein interesse halber gerne hören/lesen 🙂

    Es gibt viele Möglichkeiten das umzusetzen.
    Ein weiteres Beispiel:

    #include <iostream>
    #include <iterator>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <boost/foreach.hpp>
    int main() {
    	typedef std::istream_iterator<std::string> strIter;
    	strIter begin(std::cin), end;
    	std::vector<std::string> vec(begin,end);
    	BOOST_FOREACH(std::string& word, vec) {
    		std::reverse(word.begin(),word.end());
    		std::cout<<word<<" ";
    	}
    	return 0;
    }
    

    Ausgabe:

    Ich esse gerne
    Wurst
    und Kaese
    ^Z
    hcI esse enreg tsruW dnu eseaK
    


  • rettich schrieb:

    erstmal vielen dank für die wirklich schnelle bearbeitung meines problems.
    @CStoll

    die innere schleife:

    for(k,j=i;k<=i&&j!=' ';j--,k++)
    

    k=0 :wurde lokal für die ganze main funktion initialisiert da der wert fortlaufend
    sein soll und nicht bei jedem schleifen aufruf wieder bei 0 beginnen darf da ja sonst das erste wort in invert jedesmal überschrieben wird oder?

    OK, das hatte ich übersehen. Aber wenn das so ist, kannst du es in der Schleifen-Initialisierung auch komplett weglassen.

    und j!=' ' :als untere begrenzung des wortes.
    es fehlt natürlich die untere begrenzung des ersten wortes,
    das hab ich allerdings getestet und macht keinen unterschied
    im ergebnis

    im übrigen Quelltext verwendest du j als Index in deinem Eingabestring, das solltest du an dieser Stelle auch machen, sprich satz[j]!=' ' . Du vergleichst an der Stelle deinen Index mit dem ASCII-Code des Leerzeichens (auf den meisten Rechnern gleich 32), d.h. wenn das erste Wort der Eingabe nicht zufällig lang genug ist, liest du ziemlich schnell über den Anfang des Strings hinaus in Bereichen, in denen du nichts zu suchen hast. Aus dem selben Grund fehlt noch eine Abbruchbedingung j>=0 in der Schleife - nur für den Fall, daß vor dem ersten Wort kein Leerzeichen steht.

    Eine Lösung hätte ich auch noch:

    size_t pos, end = 0;
    do
    {
      pos = satz.finde_first_not_of(' ', end);
      end = satz.find_first_of(' ', pos);
      string word = satz.substr(pos, end==string::npos ? string::npos : end-pos);
      reverse(word.begin(),word.end());
      cout<<word<<' ';// alternativ auch inverse += word + ' ';
    while( end != string::npos );
    

    (ohne Garantie - ich bin etwas aus der Übung)


Anmelden zum Antworten