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



  • 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