[gelöst]kleines Problem mit meinem ersten größeren C++ Programm (Unterprogramm)



  • Hi,

    ich hab ein kleines Problem bei einem Programm. Hab grade das erste Semester programmieren und wir sollen als Übung ein Prog schreiben, dass ein Menü anzeigt und verschiedene Sachen je nach Auswahl durchführt.

    Die Kommentare sind ausreichend, sollte man durchblicken können.

    Nun läuft eigentlich alles bis auf ein Problem in einem Unterprogramm.

    Ich poste mal das Prog und separiere betreffenden Abschnitt.

    /*	File: menueauswahl.cpp
    	Date: 10.11.09 12:46 CET
    
    	Author(s): 
    
    	License information:
    
    	Copyright (C) [2009] []
    
    	This program is free software; you can redistribute it and/or modify it under
    	the terms of the GNU General Public License as published by the	Free Software
    	Foundation; either version 3 of the License, or (at your option) any later
    	version. This program is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    	FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
    	details. You should have received a copy of the GNU General Public License along with this
    	program; if not, see <http://www.gnu.org/licenses/>.	
    
    	Written with: Kate
    	Program name: Menüauswahl mit Aktion
    	What this program does: User chooses an action out of a few options.
    
    				Options:	* round a decimal number
    						* toggle a letter's case
    						* print the ASCII Table
    	Compiling instructions: 
    
    		g++: 	For UNIX machines please do a "g++ -o [YourProgramsName] ThisFilesName.cpp"
    			To execute the bin file type ./YourProgramsName
    			With no [YourProgramsName] given, the outfile will be "a.out"
    
    			For Windows machines please do a "g++ -o YourProgramsName.exe ThisFilesName.cpp"
    			and just start that executable.
    
    			To get Warnings: "g++ -Wall -o YourProgramsName ThisFilesName.cpp" 
    
    		cl.exe: cl /EHsc ThisFilesName.cpp
    			cl /Fe YourFilesName.exe /EHsc ThisFilesName.cpp
    			cl /EHsc /W4 ThisFilesName.cpp (Warning Level 4)
    
    		Usage of g++ is highly recommended! Sprit of free software! Microsoft is evil! ;-)
    
    	Have fun!
    */
    
    #include <iostream>		//includes iostream header
    //#include <ctype>		//maybe later needed for alternative case toggle with tolower() and toupper()
    #include <cstdio>
    
    using namespace std;							//makes std namespace available
    
    void asciiCodeOutput();							//sub for ASCII Table
    void roundDecimal();							//sub for rounding a decimal
    void toggleLetterCase();						//sub for switching a letters case
    void usageInstructions();						//sub for usage Instructions 
    
    int main()
    
      {
    
        cout << "Wilkommen zum Beispielprogramm \"Menüauswahl\" mit Aktion" << endl;	//Shows Menu
        cout << endl;
        cout << "Bitte wählen Sie eine Option aus!" << endl;
        cout << endl;
        cout << "a , A: Ausgabe des vollständigen ASCII-Zeichensatzes" << endl;
        cout << "r : Eine Dezimalzahl auf ganze Zahl runden" << endl;
        cout << "u : Umwandlung von Buchstaben (gross <-> klein)" << endl;
        cout << "b , x: Beenden" << endl;
        cout << endl;
        cout << "Bitte treffen Sie nun Ihre Auswahl: ";
        char letter;							//User given char "letter"
        cin >> letter;							//Reads "letter"
    
        switch (int(letter))						//Case selection for "buchstabe"
    
        {
          case 97:	asciiCodeOutput();					//a
    		break;
          case 65: 	asciiCodeOutput();					//A
    		break;
          case 114:	roundDecimal();						//r
    		break;
          case 117: toggleLetterCase();					//u
    		break;
          case 98:	return 0;						//b
          case 120:	return 0;						//x
          default: 	usageInstructions();					//if other input	
        }
    
      }
    
    void asciiCodeOutput()
    
      {   
    
        int i;										//Counter value
        i = 0;
    
        cout << endl;
        cout << "Die ASCII-Tabelle" << endl;
        cout << endl;
    
        do 								//loop to display each ASCII character
    
        {
         cout << i << ": " << char(i) << endl;			//Character with its integer value
         i = i + 1;
        }  
    
        while(i <= 127);
    
        cout << endl;
        cout << "Bitte [ENTER] zum Fortfahren drücken" << endl;		//Enter key to return
    
        int c;								//clears the input buffer
        while ((c = getchar()) != EOF && c != '\n');			//getchar() til no char is left
    
        getchar();								//waits for key to continue
    
        main(); 								//back to menu
    
      }
    
    void roundDecimal()
    
      {
    
        cout << "Bitte geben Sie eine Dezimalzahl (+/-) Ihrer Wahl ein!" << endl;	//ask for decimal
        cout << "Benutzen Sie einen Punkt als Komma!" << endl;
    
        double decimal;								//decimal 
        double toRound;								//to decide if up or down
        int rounded;								//rounded Value
    
        cin >> decimal;								//read it!
    
        if( decimal < 0 )							//if negative or zero/positive
    
        {
    
          toRound = (decimal * -1) - (int(decimal) * -1); 			//absolute value to calc with
    
        }
    
        else 
    
        {
    
          toRound = decimal - int(decimal);
    
        }
    
        if( toRound >= 0.5 && decimal < 0 )								//round up
    
        {
    
          rounded = int(decimal) - 1;
    
        }
    
        else if( toRound >= 0.5 )
    
        {
    
          rounded = int(decimal) + 1;
    
        }
    
        else										//round down
    
        {
    
          rounded = int(decimal);
    
        }
    
        cout << "Ihre eingegeben Zahl ist gerundet: " << rounded << endl;		//output of rounded decimal
        cout << endl;
    
        cout << "Bitte [ENTER] zum Fortfahren drücken"  << endl;			//press button to return
    
        int c;									//clears the input buffer
        while ((c = getchar()) != EOF && c != '\n');				//getchar() til no char is left
    
        getchar();									//waits for key to continue
    
        main(); 									//back to menu
    
      }
    
    void toggleLetterCase()
    
      {
    
        cout << "Bitte geben Sie einen Buchstaben (klein oder gross, a-z, A-Z) ein!" << endl;  // Letter needed
    
        char toToggle;									   //users letter
        char toggled;									   //toggled letter
    
        cin >> toToggle;									   //read it
    
        cout << endl;
        cout << "Das von Ihnen eingegebe Zeichen lautet: " << toToggle << endl;	//output of given letter
        cout << endl;
    

    Jetzt kommt der Abschnitt mit den Problemen:

    //if no a-z letter:
    
        if( int(toToggle) < 65 || int(toToggle) > 122 || (int(toToggle) > 90 && int(toToggle) < 97 ) ) 
    
        {
    
          cout << "Dies ist kein Buchstabe. Bitte geben Sie einen Buchstaben (a-z, A-z) ein)" << endl;
          toggleLetterCase();
    
        }
    

    Wenn der Nutzer ein einzelnes Zeichen, das kein Buchstabe ist eingibt, funktioniert alles prächtig. Aber wenn er nun mehrere (bspw ziffern) hintereinander eingibt, dann passiert folgendes: toggleLetterCase() wird neu aufgerufen. Nun gebe ich einen richtigen Buchstaben ein. Dieser wird umgewandelt und korrekt angezeigt. Dann geht es mit Enter zurück ins Hauptmenü. Wenn jetzt bei der Auswahl bspw "x" zum Beenden eingegeben wird, dann haut das Programm solange wieder "Dies ist ihr umgewandelter Buchstabe, Weiter mit Enter" raus, wie der Nutzer vorher "nicht-Buchstaben" hintereinander eingegeben hat. Scheint an dem Aufruf des Unterprogramms aus sich selbst zu liegen.

    else if( int(toToggle) <= 90 )								//if it's capital
    
        {
    
          toggled = char( int(toToggle) + 32 );
    
        }
    
        else toggled = char( int(toToggle) - 32 );							//if it's lower case
    
        cout << "Dies ist ihr umgewandelter Buchstabe: " << toggled << endl;			//output of toggled letter
    
        cout << "Bitte [ENTER] zum Fortfahren drücken"  << endl;			//press button to return
    
        int c;									//clears the input buffer
        while ((c = getchar()) != EOF && c != '\n');				//getchar() til no char is left
    
        getchar();									//waits for key to continue
    
        main(); 									//back to menu
    
      }
    
    void usageInstructions()
    
      {
    
        cout << "Ihre Eingabe konnte nicht verarbeitet werden." << endl;			//if any other input given press Enter to return
        cout << "Bitte wählen Sie eine der gültigen Optionen aus [a,A,r,u,b,x]!" << endl;
        cout << "Zurück zum Menü mit [Enter]!" << endl;
    
        int c;									//clears the input buffer
        while ((c = getchar()) != EOF && c != '\n');				//getchar() til no char is left
    
        getchar();									//waits for key to continue
    
        main(); 									//back to menu
    
      }
    

    Bin für jede Hilfe dankbar.

    Gruß

    Jochen



  • vorweg:
    das hier wird sich keine sau vollständig angucken - niemand hat lust, 300zeilen code anzugucken - es sei denn, der code ist wirklich toll, aber das ist er nicht...
    schon allein die 50zeilen copyrights sind nen grund, nix zu schreiben, aber einen tip geb ich dir mal:

    switch (int(letter))     //Case selection for "buchstabe" 
        { 
          case 97:    asciiCodeOutput();                    //a 
            break; 
          case 65:     asciiCodeOutput();                    //A 
            break; 
          case 114:    roundDecimal();                        //r 
            break; 
          case 117: toggleLetterCase();                    //u 
            break; 
          case 98:    return 0;                        //b 
          case 120:    return 0;                        //x 
          default:     usageInstructions();                    //if other input    
        }
    

    1. sinnloser cast
    2. sinnloser kommentar hinter dem switch
    3. sinnloser kommentar hinter default
    4. statt den zahlen kann(SOLLTE) man den buchstaben schreiben:
    5. wenn versch. zahlen haargenau das selbe machen, muss man das nich 2x schreiben:

    case 'a':
          case 'A':
            asciiCodeOutput();
            break;
    

    räum deinen code ma ein wenig auf und lass das unnötige weg und stell vll au ma ne konkrete frage... xD ich seh genau genommen gar keine...

    bb



  • Hallo und grundsätzlich mal danke für Deine Antwort.

    unskilled schrieb:

    vorweg:
    es sei denn, der code ist wirklich toll, aber das ist er nicht...

    Weißt Du, für mich ist der Code toll, weil er im Grunde funktioniert und ich ihn selbst geschrieben habe. Und ich grade paar Stunden an dem Thema erst dran bin. Was soll ich denn posten, wenn nicht den ganzen Code, sonst kann sich jka keiner ein Bild davon machen.

    schon allein die 50zeilen copyrights sind nen grund, nix zu schreiben

    Ok die hätt ich weglasse können. Sinnvoll sind die aber auf jeden Fall.
    Manch freier Code hat weit mehr als 50 Zeilen im Header.
    Und was sollich posten, wenn nicht das ganze Programm, sonst kann sich ja niemand ein Bild von dem Problem machen.

    aber einen tip geb ich dir mal:

    1. sinnloser cast

    Was ist ein cast?

    2. sinnloser kommentar hinter dem switch
    3. sinnloser kommentar hinter default

    Wer entscheidet über Sinn und Unsinn? Weiss ich ob mein Prof nicht rummeckert wenn dort ein Kommentar fehlt? Lieber zu viel als zuwenig Kommentieren. Sagt mir die gesunde Logik und die Anweisung von unserm Prof.

    4. statt den zahlen kann(SOLLTE) man den buchstaben schreiben:

    Das stimmt, hab ich grade erst dank Dir nochmal nachgeschlagen. Irgendwie hatte ich im Kopf dass switch nur mit integerwerten funktioniert. Aber den char direkt akzeptiert er ja auch.

    räum deinen code ma ein wenig auf und lass das unnötige weg und stell vll au ma ne konkrete frage... xD ich seh genau genommen gar keine...

    Die konkrete Frage und Problembeschreibung steht zwischen den Codeblöcken.

    Wenn du die nicht siehst, weiss ich auch nicht.

    Irgendwie frag ich mich ob ich mich nochmal trauen soll hier was zu posten. Da wird man ja fast so beantwortet wie im Debianforum....

    Gruß und nochmal danke

    Jochen


  • Mod

    Ein ganz gravierender fehler in deinem Code: Man darf die main funktion nicht selber aufrufen. Mach stattdessen eine Schleife um dein Hauptmenü.



  • Ich gehöre nicht zu den Leuten, die sich ellenlangen Code hier durchlesen wenn obendrüber nicht mal ansatzweise ne Frage steht...
    Und wenn ich jeden Kommentar in deinem Quelltext nach Fragen durchsuchen muss, ist das auch nicht die allerdollste Lsg., meinst du nicht auch?

    "Wer entscheidet über Sinn und Unsinn?"
    switch (int(letter)) //Case selection for "buchstabe"
    ist so was sinnvoll?

    default: usageInstructions(); //if other input
    hältst du das für sinnvoll?

    wenn man code an sich kommentieren muss, ist das schon fast immer ein zeichen für unleserlichen code...

    (switch geht mit allen ganzzahligen integralen datentypen: char, unsigned/signed char, unsigned/signed short, unsigned/signed int, unsigned/signed long (und unsigned/signed long long))

    "was ist ein cast?"
    ich denke, du hast den code selbst geschrieben? Oo
    ansonsten: google halt mal nach "c++ cast" oder so was...

    int i;                                        //Counter value
        i = 0;
    
        cout << endl;
        cout << "Die ASCII-Tabelle" << endl;
        cout << endl;
    
        do                                 //loop to display each ASCII character
    
        {
         cout << i << ": " << char(i) << endl;            //Character with its integer value
         i = i + 1;
        }  
    
        while(i <= 127);
    
    std::cout << "Die ASCII-Tabelle" << std::endl;
    for(char i = 0; i < 127; ++i)
      std::cout << int(i) << ": " << i << std::endl;
    std::cout << int(i) << ": " << char(128) << std::endl;
    

    oder wenn du es korrekt machen möchtest:

    #include <limits>
    
    std::cout << "ascii" << std::endl;
    for(char i(std::numeric_limits<char>::min()); i != std::numeric_limits<char>::max(); ++i)
      std::cout << int(i) << ": " << i << std::endl;
    std::cout << int(std::numeric_limits<char>::max()) << ": " << std::numeric_limits<char>::max() << std::endl;
    

    numeric_limits<char>
    sind die grenzen des datentyps char:
    min() = minimum
    max() = maximum

    die ausgabe an sich könntest du vll noch in ne fkt stopfen oder so...

    cout << endl;
        cout << "Bitte [ENTER] zum Fortfahren drücken" << endl;        //Enter key to return
    
        int c;                                //clears the input buffer
        while ((c = getchar()) != EOF && c != '\n');            //getchar() til no char is left
    
        getchar();                                //waits for key to continue
    

    hier gehts weiter - getchar() sollte alles akzeptieren, nicht nur enter
    wenns eh enter sein darf, dann geht das auch mit standard-mitteln:

    void wait()
    {
      std::cin.clear();
      std::cin.ignore(std::cin.rdbuf()->in_avail());
      std::cin.get();
    }
    

    die methode musst du zwar nicht unbedingt verstehen, aber sie geht folgendermaßen:
    clear: alle fehlerflags zurücksetzen
    ignore: alle zeichen im buffer ignorieren
    get: auf eine eingabe warten(die ja bekanntlich mit enter abgeschlossen wird) -> auf enter warten

    roundDecimal
    geht kaum umständlicher (dafür gibt es schon fertige fkt).
    und die leerzeilen nach jeder zeile machen es auch nicht gerade lesbarer...

    für das toggle gibt es auch fkt aus der standard-bibliothek, wenn du die nicht nutzen darfst, würde ich dir empfehlen, es ähnlich anzustellen(is_alpha -> is_lower / is_upper ... usw.) und halt die fkt dann selbst zu schreiben...

    auch dort solltest du wieder mit zeichen statt zahlen arbeiten('a' statt 63 oder was auch immer a in der ascii tabelle ist...)

    wenn du das so weit hast, kannst du ja mal posten, wie dein quellcode aussieht...
    Dein fehler an sich sollte jedoch weggehen, wenn du SeppJ`s Vorschlag befolgst...

    bb



  • This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License...

    Echt großzügig - das war mein bester Lacher heute. 🙂



  • ROFLMAO schrieb:

    This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License...

    Echt großzügig - das war mein bester Lacher heute. 🙂

    Was denn?
    Standard Lizenztext halt.



  • Bausparfuchs schrieb:

    Und was sollich posten, wenn nicht das ganze Programm, sonst kann sich ja niemand ein Bild von dem Problem machen.

    Lies dir mal den Thread "Du brauchst Hilfe?" durch (Link auch in meiner Sig), da gibts ne Antwort auf genau diese Frage.



  • Bausparfuchs schrieb:

    Wer entscheidet über Sinn und Unsinn? Weiss ich ob mein Prof nicht rummeckert wenn dort ein Kommentar fehlt? Lieber zu viel als zuwenig Kommentieren. Sagt mir die gesunde Logik und die Anweisung von unserm Prof.

    Die "gesunde Logik" ist ein Mythos an den zwar viele glauben die es aber nicht gibt. Das was Du hier meinst ist die "subjektive Logik" in der Du das als logisch ansiehst was in Deinen Augen logisch ist, also ein Kreisschluß. Dabei nimmst Du als Grundlage Deinen aktuellen Wissensstand und postulierst basierend auf diesem "Logische Aussagen".

    Zugegeben ich (wir) machen das auch, nur ist unser Wissenstand etwas umfangreicher. Eine Absolute Logik gibt es (leider) nicht... In deinem Fall würde ich sogar dazu neigen zu sagen: Logisch ist was der Prof fordert, egal wie schwachsinnig das für erfahrene Leute klingen mag.

    Zum Thema Kommentieren: So wenig wie möglich, soviel wie nötig. Trivialkommentierung sollte man vermeiden.



  • Bausparfuchs schrieb:

    Die konkrete Frage und Problembeschreibung steht zwischen den Codeblöcken.

    Üblicherweise sollte man versuchen, aus seinem Code ein Minimalbeispiel herauszuziehen, dass den Fehler hervorruft, aber nicht mehr als nötig beinhaltet, um eben die Leute hier nicht unnötig zu verwirren bzw. zu vergraulen (denn das ist hier schließlich ein freiwilliger Dienst, und kaum jemand hat Lust, einen Riesen-Code wegen eines viel kleineren Problems zu durchforsten). Was soll's, du bist schon genug fertig gemacht worden, beim nächsten Mal weißt du ja bescheid. 🙂



  • So danke nochmal für die Antworten. Hat mir schon geholfen. Muss mal bei den Comments bissl aufräumen. Hab ich auch schon.

    ich denke, du hast den code selbst geschrieben? Oo
    ansonsten: google halt mal nach "c++ cast" oder so was...

    Typkonversion = Cast. Alles klar.

    #include <limits>
    
    std::cout << "ascii" << std::endl;
    for(char i(std::numeric_limits<char>::min()); i != std::numeric_limits<char>::max(); ++i)
      std::cout << int(i) << ": " << i << std::endl;
    std::cout << int(std::numeric_limits<char>::max()) << ": " << std::numeric_limits<char>::max() << std::endl;
    

    1. Ist das std:: denn wirklich nötig, wenn ich oben "using namespace std" nutze?
    2. Bei den Grenzen ist das so ein Problem. klar gehn sie von -128 bis 127. Das Problem hierbei ist, dass nur 0-127 auf allen Systemen korrekt angezeigt wird.
    Bei mir im Linux zumindest haut er bei -128 bis -1 nur müll raus. Und die Standard ASCII Tabelle ist ja nur 128 Zeichen. Die erweiterte auf 255 macht wie gesagt diese unvorhersehbaren Sachen in der Ausgabe.

    hier gehts weiter - getchar() sollte alles akzeptieren, nicht nur enter
    wenns eh enter sein darf, dann geht das auch mit standard-mitteln:

    Ja schon aber du musst doch eh Enter drücken, um dann die eingabe zu übernehmen. Wenn da nur ne Taste gedrückt wird, passiert ja noch nix. Deswegen hab ichs so geschrieben.

    roundDecimal
    geht kaum umständlicher (dafür gibt es schon fertige fkt).
    [...]
    für das toggle gibt es auch fkt aus der standard-bibliothek, wenn du die nicht nutzen darfst, würde ich dir empfehlen, es ähnlich anzustellen(is_alpha -> is_lower / is_upper ... usw.) und halt die fkt dann selbst zu schreiben...

    Stimmt schon alles aber ich denke immer, dass wenn wir in der Übung mit Code ankommen, der noch nicht behandelt wurde, gibts mecker.

    Dein fehler an sich sollte jedoch weggehen, wenn du SeppJ`s Vorschlag befolgst...

    bb

    Jap funktioniert.

    Danke auch an SeppJ dafür.

    ROFLMAO schrieb:

    This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License...

    Echt großzügig - das war mein bester Lacher heute. 🙂

    Freut mich, dass ich dienen Tag ein wenig versüßen konnte.
    Ich weiss nicht mit welchen Programmen du arbeitest, aber in 90% der Programme, die ich benutze, steht eben genau dieser Text in jeder einzelnen Codedatei drin.

    Das kann man natürlich nur lesen, wenn die offengelegt werden. Deswegen kennst Du diesen Text scheinbar nicht....
    Ob nun jemand Interesse hat, so ein quasi sinnloses Programm im Rahmen dieser Lizenz zu modifizieren oder was auch immer, tut doch garnix zur Sache, oder?

    Gruß

    Jochen



  • Ist das std:: denn wirklich nötig, wenn ich oben "using namespace std" nutze?

    Nein.

    Stimmt schon alles aber ich denke immer, dass wenn wir in der Übung mit Code ankommen, der noch nicht behandelt wurde, gibts mecker.

    Ich denke nicht, das er meckern wird, wenn Du etwas mehr Standardfeatures nutzt. Es ist ja offensichtlich nicht verboten, die zu nutzen, weil Du das ja schon tust.
    Andererseits, warum nicht eine eigene Fkt. schreiben? Übung schadet nicht.

    Freut mich, dass ich dienen Tag ein wenig versüßen konnte.
    Ich weiss nicht mit welchen Programmen du arbeitest, aber in 90% der Programme, die ich benutze, steht eben genau dieser Text in jeder einzelnen Codedatei drin.

    Ich glaube, in deinem Stadium des Programmierens kannst Du die Lizenz getrost weglassen; Das kopiert niemand bzw. es nutzt niemand wirklich was. Es vergrößert einfach nur die Quelldateien und hindert z.B. uns daran, schnell Deinen Code zu lesen.
    Du kannst das natürlich gerne in all deine Header schreiben, aber lass es bitte hier im Forum weg, wenn Du uns um Hilfe bittest. Oder hast Du hier schon viele Hilfegesuche gesehen, wo die Lizenz beistand?



  • Nochwas:

    Hat Dir schon jemand empfohlen, etwas weniger Leerzeilen zu lassen? Das macht den Code kürzer und übersichtlicher, als wenn plötzlich irgendwo 3!!! Zeilen frei sind:

    { 
    
        cout << "Bitte geben Sie eine Dezimalzahl (+/-) Ihrer Wahl ein!" << endl; //ask for decimal 
        cout << "Benutzen Sie einen Punkt als Komma!" << endl; 
    
        double decimal;                                //decimal 
        double toRound;                                //to decide if up or down 
        int rounded;                                //rounded Value 
    
        cin >> decimal;                                //read it! 
    
        if( decimal < 0 )                            //if negative or zero/positive 
    
        { 
    
          toRound = (decimal * -1) - (int(decimal) * -1);             //absolute value to calc with 
    
        } 
    
        else 
    
        { 
    
          toRound = decimal - int(decimal); 
    
        }
    

    Das liest sich doch so:

    { 
        cout << "Bitte geben Sie eine Dezimalzahl (+/-) Ihrer Wahl ein!" << endl; //ask for decimal 
        cout << "Benutzen Sie einen Punkt als Komma!" << endl; 
    
        double decimal; //decimal 
        double toRound; //to decide if up or down 
        int rounded; //rounded Value 
    
        cin >> decimal; //read it! 
    
        if( decimal < 0 ) //if negative or zero/positive 
        {
            toRound = (decimal * -1) - (int(decimal) * -1); //absolute value to calc with
        } 
        else 
        {
            toRound = decimal - int(decimal);
        }
    

    viel besser, oder? Zudem, Kommentare wirken auch schöner wenn sie, wie in meinem Beispiel nicht oder alternativ wenigstens gleichmäßig eingerückt sind (vielleicht mit Tabulator), wenn man schon sowas schreiben muss (Eigentlich sinnlos, nur nochmal den Variablennamen dahinter zu schreiben, wo er da doch schon steht):

    double decimal; //decimal
    


  • Mr X schrieb:

    Zudem, Kommentare wirken auch schöner wenn sie, wie in meinem Beispiel nicht oder alternativ wenigstens gleichmäßig eingerückt sind (vielleicht mit Tabulator)

    Nein - eben nicht mit Tabulatoren...
    Für kosmetische Sachen _immer_ Leerzeichen nehmen, nur für das Einrücken an sich Tabs nutzen...
    Tabweiten können umgestellt werden -> zu was das führt, sieht man hier ja gut...

    bb

    PS: "Hat Dir schon jemand empfohlen, etwas weniger Leerzeilen zu lassen" Jopp, hat scho jmd getan 😛 Aber ich hatte nen anderes Bsp aus seinem Quellcode genannt^^



  • unskilled schrieb:

    Mr X schrieb:

    Zudem, Kommentare wirken auch schöner wenn sie, wie in meinem Beispiel nicht oder alternativ wenigstens gleichmäßig eingerückt sind (vielleicht mit Tabulator)

    Nein - eben nicht mit Tabulatoren...
    Für kosmetische Sachen _immer_ Leerzeichen nehmen, nur für das Einrücken an sich Tabs nutzen...
    Tabweiten können umgestellt werden -> zu was das führt, sieht man hier ja gut...

    😮
    Stimmt Du hast Recht...

    PS: "Hat Dir schon jemand empfohlen, etwas weniger Leerzeilen zu lassen" Jopp, hat scho jmd getan 😛 Aber ich hatte nen anderes Bsp aus seinem Quellcode genannt^^

    Hab ich garnicht gesehen, bei soviel schon gegebenen tipps



  • Damit Ihr seht, dass ich sehr wohl lernfähig bin 😉 hier mal als Abschluss nochmal meinen vorläufigen 100% funktionierenden Code mit weniger Kommentaren und leerzeilen. Natürlich ohne Header. Sind aber immer noch 160 Zeilen. Muss ja keiner lesen. Das Topic wär dann abgehakt. Danke nochmal an alle.
    schraub nun noch bissl dran rum. Muss auch noch nen "Taschenrechner" programmieren.

    Gruß

    Jochen

    #include <iostream>
    //maybe later needed for alternative case toggle with tolower() and toupper()
    //#include <ctype>
    #include <cstdio>		
    using namespace std;							
    void asciiCodeOutput();							
    void roundDecimal();							
    void toggleLetterCase();						
    void usageInstructions();						
    
    int main()
      {
    	do
    	{
    	//Shows Menu
        cout << endl;
        cout << "####Wilkommen zum Beispielprogramm \"Menueauswahl mitAktion\"####";
        cout << endl;
        cout << "Bitte wählen Sie eine Option aus!" << endl;
        cout << endl;
        cout << "a , A: Ausgabe des vollständigen ASCII-Zeichensatzes" << endl;
        cout << "r : Eine Dezimalzahl auf ganze Zahl runden" << endl;
        cout << "u : Umwandlung von Buchstaben (gross <-> klein)" << endl;
        cout << "b , x: Beenden" << endl;
        cout << "################################################################";
        cout << endl;
        cout << "Bitte treffen Sie nun Ihre Auswahl: ";
        //User given char "letter"
        char letter = '\0';							
        cin >> letter;							
        //Case selection for pressed key
        switch (letter)						
         {
          case 'a':	asciiCodeOutput();					
    		break;
          case 'A': asciiCodeOutput();					
    		break;
          case 'r':	roundDecimal();						
    		break;
          case 'u': toggleLetterCase();					
    		break;
          case 'b':	return 0;						
          case 'x':	return 0;						
          default: 	usageInstructions();						
    	 }
    	}
    	while(true);
      }
    
    void asciiCodeOutput()
      {   
         int i = 0;										
        cout << endl;
        cout << "Die ASCII-Tabelle" << endl;
        cout << endl;
        //loop to display each ASCII-128 character with its integer value
        do
        {
         cout << i << ": " << char(i) << endl;			
         i = i + 1;
        }  
        while(i <= 127);
        cout << endl;
        //Clearing of input buffer and Enter to continue
        cout << "Bitte [ENTER] zum Fortfahren drücken" << endl;		
        int c = 0;								
        while ((c = getchar()) != EOF && c != '\n');		
    	getchar();
      }
    
    void roundDecimal()
      {
        cout << "Bitte geben Sie eine Dezimalzahl (+/-) Ihrer Wahl ein!" << endl;	
        cout << "Benutzen Sie einen Punkt als Komma!" << endl;
        //decimal: user given; toRound: value after point; rounded: rounded value
    	double decimal = 0.0;
        double toRound = 0.0;
        int rounded = 0;
        cin >> decimal;
    	//if its negative or positive to avoid using <cmath> with absf()
        if( decimal < 0 )
        {
          toRound = (decimal * -1) - (int(decimal) * -1); 
    	}
        else
        {
         toRound = decimal - int(decimal);
    	}
    	//Round-to-nearest
    	if( toRound >= 0.5 && decimal < 0 )
        {
         rounded = int(decimal) - 1;
        }
        else if( toRound >= 0.5 )
        {
         rounded = int(decimal) + 1;
        }
        else
        {
         rounded = int(decimal);
        }
        cout << "Ihre eingegeben Zahl ist gerundet: " << rounded << endl;
        cout << endl;
        cout << "Bitte [ENTER] zum Fortfahren drücken"  << endl;
        int c = 0;
        while ((c = getchar()) != EOF && c != '\n');
        getchar();
      }
    
    void toggleLetterCase()
      {
    	bool falseInput = 0;
    	//loops as long as user makes a falseInput
    	do
    	{
    	falseInput = 0;
    	cout << "Bitte geben Sie einen Buchstaben (klein oder gross, a-z,A-Z)\
    	ein!" << endl;  
    	//Letter to toggle 
    	char toToggle = '\0';
        char toggled = '\0';
        cin >> toToggle;
        cout << endl;
        cout << "Das von Ihnen eingegebe Zeichen lautet: " << toToggle << endl;
        cout << endl;
        //if no a-z letter:
        if( toToggle < 'A' || toToggle > 'z' || (toToggle > 'z' &&
    	toToggle < 'a' ) )
        {
    	 falseInput = 1;
    	 cout << "Dies ist kein Buchstabe. Bitte geben Sie einen Buchstaben (a-z,\
    	 A-z) ein)" << endl;
    	}
    	//lower to upper and vice versa
        else if( toToggle <= 'Z' )
        {
          toggled = char(toToggle + 32);
        }
        else
    	{
    	toggled = char(toToggle - 32);
    	//output of toggled letter
    	cout << "Dies ist ihr umgewandelter Buchstabe: " << toggled << endl;
        cout << "Bitte [ENTER] zum Fortfahren drücken"  << endl;
        int c = 0;
        while ((c = getchar()) != EOF && c != '\n');
        getchar();
    	}
    	}
    	while(falseInput);
      }
    
    void usageInstructions()
      {
    	//usage instructions if any other input given
    	cout << "Ihre Eingabe konnte nicht verarbeitet werden." << endl;
        cout << "Bitte wählen Sie eine der gültigen Optionen aus [a,A,r,u,b,x]!";
    	cout << endl;
        cout << "Zurück zum Menü mit [Enter]!" << endl;
        int c = 0;
        while ((c = getchar()) != EOF && c != '\n');
        getchar();
      }
    


  • Hehe, jetzt hast du alle Leerzeilen weggelassen... 😃

    Nimm die goldene Mitte. Nicht jede zweite Zeile muss leerstehen, aber wenn man in einer Funktion einen gedanklich zusammenhängenden Block von 5, 6 Zeilen hat, darf dieser ruhig durch Leerzeilen zum Zwecke der Übersicht vom Rest abgetrennt werden.

    Und an deiner Einrückung könntest du auch noch ein wenig arbeiten. Immer wenn du einen Scope (geschweifte Klammer) beginnst, gehst du einen Tab nach rechts, beim Schließen einen nach links.

    if() {
      while() {
        if() {
          for() {
            //...
          }
        }
        if() {
          //...
        }
      }
    }
    

    Oder halt so, wenn man drauf steht:

    if()
    {
      while()
      {
        if()
        {
          for()
          {
            //...
          }
        }
        if()
        {
          //...
        }
      }
    }
    


  • Erstmal: Sieht jetzt viel besser aus. Kommentare sind nicht mehr unsinnig. Wie allerdings schon von matze gesagt, nicht alle Leerzeilen stören, nur viele am Stück und ohne Kontext-Zusammenhang. Auch zum Thema Einrückungen stimme ich meinem Vorredner zu.

    Nochetwas, was schon erwähnt wurde, dass Du gut umsetzen könntest:

    case 'a':    asciiCodeOutput();                    
            break;
          case 'A': asciiCodeOutput();                    
            break;
    

    kann zu

    case 'a': case 'A': asciiCodeOutput();                    
            break;
    

    vereinfacht werden. Ebenso solltest Du dir noch for-Schleifen ansehen, wenn Ihr die noch nicht hattet, und sie einsetzen. (Sind übersichtlicher als manche deiner do-while-Schleifen (Überall, wo ein Zähler läuft, eignen sich for-Schleifen).

    In asciiCodeOutput() könntest Du i gleich als char deklarieren, dann kannst Du den Cast weglassen. (operator++ geht auch mit char).

    Ansonsten, Gut, vor allem, da es ja jetzt anscheinend auch tut, was es soll!



  • Danke, ich werds umsetzen.



  • Bausparfuchs schrieb:

    Danke, ich werds umsetzen.

    hoffentlich besser, als du es das letzte mal umgesetzt hast... hab ja extra zu dem switch 5 pkt geschrieben und dir dann noch nen bsp gemacht, was dazu noch lesbar ist (im ggnsazu zu dem, wo die case`s nacheinander stehen oder die erste anweisung in der selben zeile wie das case)

    bb


Anmelden zum Antworten