BeispielProgramm-alphapetisches Sortieren-Programmierstil



  • Ich bin ein C++ - Neuling und habe ein Programm zum alphabetischen Sortieren von Worten geschrieben. Von Programmierstil kann bei diesem Code wohl keine Rede sein 🙂 aber wer Lust hat kann es sich trotzdem mal anschaun und Verbesserungsvorschläge zum Stil, Lesbarkeit usw. bringen.
    Einige Fehler sind mir schon so klar.

    1. getch() möglichst vermeiden... Habe ich nicht gemacht.
    2. Ich verwende 3 counter mit den nichtssagenden Namen counter, counter2 und counter3.
    3. Ich habe den Code nicht mit Kommentaren versehen.
    4. Die erste while(1)-Schleife ist nicht so geschickt, weil die Variablen bei jedem Programmsurchlauf neu deklariert werden.
    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <conio.h>
    #include <stdio.h>
    
    int main()
    {
    while(1)
    {
    system("cls");
    int how_many;
    int asc1;
    int asc2;
    int next=0;
    int counter=0,counter2=1,counter3=0;
    cout<<"Wie viele Worte wollen Sie alphabetisch sortieren? ";
    cin>>how_many;
    
    string word[how_many];
    string word_change;
    
    cout<<"Bitte geben Sie nun die Worte ein; bestaetigen Sie jedes Wort mit Enter: "<<endl;
    
    while(counter<how_many)
    {
    cin>>word[counter];
    counter++;
    }
    counter=0;
    
    while(counter<how_many-1)
    {
    while(counter+counter2<how_many)
    {
    
    while(next==0)
    {
    asc1=(int) word[counter][counter3];
    if(asc1>=97) asc1-=32;
    asc2=(int) word[counter+counter2][counter3];
    if(asc2>=97) asc2-=32;
    
    if(asc1>asc2)
    {
    word_change=word[counter+counter2];
    word[counter+counter2]=word[counter];
    word[counter]=word_change;
    next=1;
    }
    if(asc1==asc2) counter3++;
    
    else next=1;
    
    }
    next=0;
    counter2++;
    counter3=0;
    }
    counter2=1;
    counter++;
    }
    counter=0;
    system("cls");
    
    while(counter<how_many)
    {
    cout<<word[counter]<<endl;
    counter++;
    }
    getch();
    }
    }
    

    Danke für jede Antwort



  • Hallo

    also das kann man so zusammenfassen

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    
    void wait ()
    {
        std::cin.clear();
        std::cin.ignore(std::cin.rdbuf()->in_avail());
        std::cin.get();
    }
    
    int main()
    {
    	std::cout << "Enter Words separated by Enter. Enter empty line for exit" << std::endl;
    	std::string line; // aktuelle Eingabe
    	std::vector<std::string> lines; // Dynamisches Array für Eingaben
    
            // Solange Sätze eingeben lassen und speichern bis eine leere Eingabe kommt
    	do
    	{
          std::getline(std::cin, line);
          lines.push_back(line);
    	} while (line.size() > 0);
    
            // Eingaben sortieren
    	std::sort(lines.begin(), lines.end());
    
            // Sortierte Eingaben der Reihe nach wieder ausgeben
    	std::cout << std::endl << "sorted lines : " << std::endl;
    	for (std::vector<std::string>::iterator it = lines.begin(); it != lines.end(); ++it)
    	  std::cout << *it << std::endl;
    
        wait();
    	return 0;
    }
    


  • Ertsmal vielen Dank. Mal abgesehen davon, dass ich den Code nicht verstehe sortiert er allerdings Worte mit grossem und kleinem Anfangsbuchstaben falsch.
    Trotzdem Danke



  • Hab deinen Code mal formatiert, jetzt kann ich ihn mir besser ansehen.

    #include <iostream> 
    #include <string> 
    #include <stdlib.h> 
    #include <conio.h> 
    #include <stdio.h> 
    using namespace std;
    int main() 
    { 
       while(1) 
       { 
          system("cls"); 
          int how_many; 
          int asc1; 
          int asc2; 
          int next=0; 
          int counter=0,counter2=1,counter3=0; 
          cout<<"Wie viele Worte wollen Sie alphabetisch sortieren? "; 
          cin>>how_many; 
    
          string word[how_many]; 
          string word_change; 
    
          cout<<"Bitte geben Sie nun die Worte ein; bestaetigen Sie jedes Wort mit Enter: "<<endl; 
    
          while(counter<how_many) 
          { 
             cin>>word[counter]; 
             counter++; 
          } 
          counter=0; 
    
          while(counter<how_many-1) 
          { 
             while(counter+counter2<how_many) 
             { 
    
                while(next==0) 
                { 
                   asc1=(int) word[counter][counter3]; 
                   if(asc1>=97) asc1-=32; 
                      asc2=(int) word[counter+counter2][counter3]; 
                   if(asc2>=97) asc2-=32; 
                      if(asc1>asc2) 
                      { 
                         word_change=word[counter+counter2]; 
                         word[counter+counter2]=word[counter]; 
                         word[counter]=word_change; 
                         next=1; 
                      } 
                   if(asc1==asc2) counter3++; 
                   else next=1; 
                } 
                next=0; 
                counter2++; 
                counter3=0; 
             } 
             counter2=1; 
             counter++; 
          } 
          counter=0; 
          system("cls"); 
    
          while(counter<how_many) 
          { 
             cout<<word[counter]<<endl; 
             counter++; 
          } 
          getch(); 
       } 
    }
    

    🙂



  • Hab deinen Code mal formatiert, jetzt kann ich ihn mir besser ansehen.

    #include <iostream> 
    #include <string> 
    #include <stdlib.h> 
    #include <conio.h> 
    #include <stdio.h> 
    using namespace std;
    int main() 
    { 
       while(1) 
       { 
          system("cls"); 
          int how_many; 
          int asc1; 
          int asc2; 
          int next=0; 
          int counter=0,counter2=1,counter3=0; 
          cout<<"Wie viele Worte wollen Sie alphabetisch sortieren? "; 
          cin>>how_many; 
    
          string word[how_many]; 
          string word_change; 
    
          cout<<"Bitte geben Sie nun die Worte ein; bestaetigen Sie jedes Wort mit Enter: "<<endl; 
    
          while(counter<how_many) 
          { 
             cin>>word[counter]; 
             counter++; 
          } 
          counter=0; 
    
          while(counter<how_many-1) 
          { 
             while(counter+counter2<how_many) 
             { 
    
                while(next==0) 
                { 
                   asc1=(int) word[counter][counter3]; 
                   if(asc1>=97) asc1-=32; 
                      asc2=(int) word[counter+counter2][counter3]; 
                   if(asc2>=97) asc2-=32; 
                      if(asc1>asc2) 
                      { 
                         word_change=word[counter+counter2]; 
                         word[counter+counter2]=word[counter]; 
                         word[counter]=word_change; 
                         next=1; 
                      } 
                   if(asc1==asc2) counter3++; 
                   else next=1; 
                } 
                next=0; 
                counter2++; 
                counter3=0; 
             } 
             counter2=1; 
             counter++; 
          } 
          counter=0; 
          system("cls"); 
    
          while(counter<how_many) 
          { 
             cout<<word[counter]<<endl; 
             counter++; 
          } 
          getch(); 
       } 
    }
    

    🙂



  • thx 🙂



  • Hallo

    std::string wird technisch nach den ASCII-Werten verglichen, und da liegen die großen Buchstaben vor den kleinen.
    Wenn dich das stört kannst du für std::sort aber auch eine eigene Vergleichsfunktion definieren, die auf Klein/Großschreibung Rücksicht nimmt.

    Wenn das noch zu komplex für dich ist, dann bleib erstmal bei deinem Prinzip, und schau das du folgendes beachtest
    - kein system(...) oder getch() verwenden. Alternativen findest du im Konsolen-Subforum
    - dann brauchst du auch nicht mehr die alten C-Header
    - du kannst anstatt den ASCII-Werten auch direkt die Chars hinschreiben, erhöt Lesbarkeit
    - eine systematische Einrückung der Codeblöcke erhöht Lesbarkeit
    - ich weiß zwar nicht auf welchem Compiler du das laufen hast, aber bei einem standardkonformen Compiler muß zumindestens nach den Include snoch

    using namespace std;
    

    hin
    - benutzte Funktionen um den Programmablauf übersichtlicher und wiederverwendbarer zu machen

    bis bald
    akari

    bis bald
    akari



  • Mit welchem Compiler hast du übersetzt?

    string word[how_many];
    

    Gibt bei mir 3 Fehlermeldungen: C2057, C2466 und C2133 (VC 8.0)
    Das ist kein C++ ! 😞



  • Mit welchem Compiler hast du übersetzt?

    string word[how_many];
    

    Gibt bei mir 3 Fehlermeldungen: C2057, C2466 und C2133 (VC 8.0)
    Das ist kein C++ ! 😞



  • Dev-C++ 4



  • Hallo

    das liegt einerseits an dem fehlenden namespace (hab ich schon angemerkt), anderseits weil in Standard-C++ auf diese Art keine dynamischen Arrays erstellt werden können, denn dort müssen die Dimensionen immer konstant sein.
    Es gibt aber bereits neuere C-Standards, wo sowas möglich ist, und manche Compiler unterstützen soetwas schon.

    Aber standardkonform zu C++ wäre ein dynamisches Array mit new zu erstellen oder std::vector zu verwenden.

    bis bald
    akari



  • akari schrieb:

    Es gibt aber bereits neuere C-Standards[...]

    Aber bislang keine Entsprechung im C++-Standard 😉



  • Squawking schrieb:

    ... aber wer Lust hat kann es sich trotzdem mal anschaun und Verbesserungsvorschläge zum Stil, Lesbarkeit usw. bringen.

    Unbedingt den Code formatieren, das Gehirn brauchts! Wenn bei verschachtelten Schleifen alles untereinander steht,
    ist das schon fast unlesbar, man kann dann die Kontrollstrukturen nicht mehr auf einen Blick erkennen.
    Mit while(1) in der ersten Schleife, haste 'ne Endlosschleife geschrieben. Wie beendet man Dein Programm?
    Mit VLA 's programmieren (string word[how_many]) mein VS2005 VC++ 8.0 kann das noch nicht, ganz zu Schweigen vom
    C++ Standard der das nicht kennt. Die String-Klasse der STL sollte auch einiges mehr können.
    Ich würd's so schreiben:

    #include <iostream>
    #include <string>
    #include<locale>
    using namespace std;
    
    void sortieren(string* StrPtr, int anzahl){
       bool flag = true;
       while(flag){
          flag = false;
          for (int i = 0; i < anzahl-1; ++i)
             if (StrPtr[i] > StrPtr[i+1]){
                swap(StrPtr[i], StrPtr[i+1]);
                swap(StrPtr[i+anzahl], StrPtr[i+anzahl+1]);
                flag = true;
             }
       }
    }
    int main() {
       locale loc ("German_Germany");	
       int anzahl;
       cout << "Wie viele Worte wollen Sie alphabetisch sortieren? "; 
       cin >> anzahl;
       if (!anzahl) return 0;
       string* StrPtr = new string [anzahl*2];
       cout<<"Bitte geben Sie nun die Worte ein; bestaetigen Sie jedes Wort mit Enter: "<<endl;
       for (int i = 0; i < anzahl; ++i){   
          cin >> StrPtr[i];
          StrPtr[i+anzahl] = StrPtr[i];
          for(size_t x = StrPtr[i].size(); x; --x)
             StrPtr[i][x-1] = tolower(StrPtr[i][x-1], loc);
       }
       sortieren(StrPtr, anzahl);
       for (int i = 0; i < anzahl; i++)
          cout << endl << StrPtr[i+anzahl];
       cout << endl;
       delete[] StrPtr;
       return 0;
    }
    

    mfg



  • Danke an Helmut S.
    Mit etwas Arbeit kann ich diesen code denke ich sehr gut verstehen und viel lernen.
    Vorerst werde ich mir aber erstmal einen ordentlichen Compiler besorgen. Meiner ist wohl etwas veraltet.



  • Habe mir nun eine neuere Version besorgt und bekomme darauf den code von Helmut auch zum laufen. Nur gibt es da noch ein Problem: Manche Worte werden nicht richtig geordnet. Ich habe es mit meinem Programm verglichen, dort funktioniert es. Hat wieder was mit der Gross-und Klein-Schreibung zu tun. kommt vor, wenn mehrere Buchstaben im Wort gross geschrieben sind.



  • Squawking schrieb:

    ... kommt vor, wenn mehrere Buchstaben im Wort gross geschrieben sind.

    Hab diesen Fehler behoben, siehe Programm. Wie gesagt, die String-Klasse der STL sollte mehr leisten, würde den Programmierern Arbeit sparen.
    mfg



  • Alles klar. Danke.Das Programm stürzt bei mir aber sofort nach Aufruf ab. Den Code werde ich mir trotzdem mal anschauen. Noch eine Frage:
    Dein Code ist im Vergleich zu meinem relativ kurz.
    Nun zu meiner Frage: Liegt das hauptsächlich daran, dass du die vorgefertigten Funktionen aus der STL benutzt?
    Ich habe ja die ganzen Sortier-Schleifen selber geschrieben und wüsste nicht, wie das kürzer gehen soll, wenn man alles selber schreibt.



  • Bei mir läufts. Ist vor allem die STL-Funktion swap(,) die meinen Code kürzer gemacht hat.
    mfg



  • Also wenn ich versuche, dass kompilierte Programm aus der Eingabeaufforderung zu starten bekomme ich folgenden Fehler:

    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application`s support team for more information.

    KA



  • Squawking schrieb:

    Also wenn ich versuche, dass kompilierte Programm aus der Eingabeaufforderung zu starten bekomme ich folgenden Fehler:

    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application`s support team for more information.

    KA

    Mit VS2005 VC++ 8.0 erstellt, funktioniert das Programm.
    Mit GNU GCC Compiler 3.4.6 (CodeBlocks 1.0) unter WindowsXP ersellt, kommt es auch bei mir zu der obigen Fehlermeldung.
    Hat jemand eine Erklärung dafür?


Anmelden zum Antworten