Programmierstil mit goto



  • Hallo,

    ich weiß, dass die Verwendung von goto verpöhnt ist.
    Für mein Problem finde ich aber derzeit keine andere Lösung, ihr könnt mir da bestimmt helfen. 🕶

    Hab ein Programm für einen Handscanner und da der Benutzer von mir vorgegebene
    Eingabemöglichkeiten hat, kann es bei falscher Benutzung zu einem Fehler kommen.

    Dieser Fehler tritt auf, wenn der Benutzer die "0" wählt und dann weiter will.
    Hier springt man zurück zum Funktionsstart.

    hier der Code:

    void Display_Satzzahl(void)
    {
    	FILE * datei;
    
    	int satz = 0;
    	int key = 0;
    	int i = -1;
    
    	char * satzzahl[6] = {"0","1","2","3","4","5"};
    
    	char * satzzahl_code[6] = {"","$090","$091","$092","$093","$094"};
    
    	char buffer[50] = "";
    
    Fehlerfall:
    	printf("\f");
    	printf("   Satzzahl:\n");
    	printf("Bitte druecken\n");
    	printf("  %c        %c",0x1E,0x1F);
    
    	while(satz == 0)
    	{		
    		drawline(0,48,111,48,1);
    		drawline(0,63,111,63,1);
    		idle();
    		key = getchar();
    		if(key == UP_KEY)
    		{
    			i++;
    			if(i == 6) i = 0;
    			printf("\f");
    			printf("   Satzzahl:\n");
    			printf("       %s",satzzahl[i]);
    			printf("\n\n  %c  Enter %c",0x1E,0x1F);
    		}
    /////////////////////////
    		else if(key == DOWN_KEY)
    		{
    			i--; 
    			if(i < 0) i = 5; 
    			printf("\f");
    			printf("   Satzzahl:\n");
    			printf("       %s",satzzahl[i]);
    			printf("\n\n  %c  Enter %c",0x1E,0x1F);
    		}
    		else if((key == TRIGGER_KEY) && (i != -1))
    		{
    			//wenn 0 gewaehlt
    			if(i == 0)
    			{
    				printf("\f");
    				printf("\n    Fehler!");		
    				delay(100);
    				i = -1;
    				goto Fehlerfall;
    			}
    			else
    			{
    				datei = fopen("Text.dat","a+");
    				fputc('-',datei);
    				fputs(satzzahl_code[i],datei);
    				fputc('\n',datei);
    				fclose(datei);		
    				//abbruch
    				satz = 1;		
    			}
    		}
    	}
    /////////////////////////
    	resetkey();
    }
    

    Vielleicht findet ihr ja eine Möglichkeit die goto- Anweisung zu umgehen.

    Gruß, fevernova 😃



  • fevernova schrieb:

    Hallo,

    ich weiß, dass die Verwendung von goto verpöhnt ist.
    Für mein Problem finde ich aber derzeit keine andere Lösung, ihr könnt mir da bestimmt helfen. 🕶

    Hab ein Programm für einen Handscanner und da der Benutzer von mir vorgegebene
    Eingabemöglichkeiten hat, kann es bei falscher Benutzung zu einem Fehler kommen.

    Dieser Fehler tritt auf, wenn der Benutzer die "0" wählt und dann weiter will.
    Hier springt man zurück zum Funktionsstart.

    Vielleicht findet ihr ja eine Möglichkeit die goto- Anweisung zu umgehen.

    Gruß, fevernova 😃

    Sorry, Einrückung ist wg. TABs blöde geworden, aber für's Prinzip sollte es reichen:

    void Display_Satzzahl(void)
    {
    	FILE * datei;
    
    	int satz = 0;
    	int key = 0;
    	int i = -1;
            int fail = 0;
    
    	char * satzzahl[6] = {"0","1","2","3","4","5"};
    
    	char * satzzahl_code[6] = {"","$090","$091","$092","$093","$094"};
    
    	char buffer[50] = "";
    
            do
            {
               fail = 0;
    	   printf("\f");
    	   printf("   Satzzahl:\n");
    	   printf("Bitte druecken\n");
    	   printf("  %c        %c",0x1E,0x1F);
    
    	   while(satz == 0)
    	   {		
    		drawline(0,48,111,48,1);
    		drawline(0,63,111,63,1);
    		idle();
    		key = getchar();
    		if(key == UP_KEY)
    		{
    			i++;
    			if(i == 6) i = 0;
    			printf("\f");
    			printf("   Satzzahl:\n");
    			printf("       %s",satzzahl[i]);
    			printf("\n\n  %c  Enter %c",0x1E,0x1F);
    		}
    /////////////////////////
    		else if(key == DOWN_KEY)
    		{
    			i--; 
    			if(i < 0) i = 5; 
    			printf("\f");
    			printf("   Satzzahl:\n");
    			printf("       %s",satzzahl[i]);
    			printf("\n\n  %c  Enter %c",0x1E,0x1F);
    		}
    		else if((key == TRIGGER_KEY) && (i != -1))
    		{
    			//wenn 0 gewaehlt
    			if(i == 0)
    			{
    				printf("\f");
    				printf("\n    Fehler!");		
    				delay(100);
    				i = -1;
    				fail = 1;
                                    break;
    			}
    			else
    			{
    				datei = fopen("Text.dat","a+");
    				fputc('-',datei);
    				fputs(satzzahl_code[i],datei);
    				fputc('\n',datei);
    				fclose(datei);		
    				//abbruch
    				satz = 1;		
    			}
    		}
    	   }
            } while(fail);
    /////////////////////////
    	resetkey();
    }
    


  • fevernova schrieb:

    ich weiß, dass die Verwendung von goto verpöhnt ist.

    Eigentlich nicht unbedingt, aber sei's drum. Eine eigene Funktion ist hier das Mittel der Wahl, würde ich sagen.

    enum {ERR, SUC};
    
    int scan_key( ... ) {
        ...
        while (satz == 0) {
            drawline(...);
            if (...) {
                ...
            } else if (...) {
                if (i == 0) {
                    ....
                    return ERR;
                }
            }
        }
        return SUC;
    }
    
    void Display_Satzzahl(void) {
        ....
       do {
            printf("\f");
            printf("   Satzzahl:\n");
            printf("Bitte druecken\n");
            printf("  %c        %c",0x1E,0x1F);
       } while (scan_key(...) == ERR);
    
        resetkey();
    }
    

    Oder so.



  • fevernova schrieb:

    ich weiß, dass die Verwendung von goto verpöhnt ist.

    schlechte programmierer benutzen oft goto
    mittelmäßige programmierer benutzen niemals goto
    gute programmierer benutzen selten goto



  • net schrieb:

    schlechte programmierer benutzen oft goto
    mittelmäßige programmierer benutzen niemals goto
    gute programmierer benutzen selten goto

    Ich habe mich oft gefragt wie man gute von mittelmäßigen Programmierern unterscheidet - jetzt weiß ich es 😃 Also ich persönlich habe bisher noch keinen Fall gesehen, bei dem man goto nicht durch eine elegantere Lösung ersetzen konnte. Ich lasse mich aber gerne eines Besseren belehren.



  • Gute Programmierer benutzen nie goto. NIE!!!!



  • Kenner guter Programmiere schrieb:

    Gute Programmierer benutzen nie goto. NIE!!!!

    Aha, zwei Mittelmaeßige Programmierer die sich aber für gute halten. ^^



  • Sehr gute Programmierer kennen kein goto!
    Die freigewordenen Gehirnzellen haben schließlich Besseres zu tun 🕶



  • Herrmann schrieb:

    Also ich persönlich habe bisher noch keinen Fall gesehen, bei dem man goto nicht durch eine elegantere Lösung ersetzen konnte. Ich lasse mich aber gerne eines Besseren belehren.

    das klassische beispiel: heraushüpfen aus einer tiefen verschachtelung mit anschliessenden aufräumarbeiten. natürlich geht das auch ohne goto, aber umständlicher. ein kleines goto statement ist dabei nun mal das eleganteste was geht.



  • Aber ist das nicht der klassische Fall für eine Exception?



  • BinSchonWeg schrieb:

    Aber ist das nicht der klassische Fall für eine Exception?

    Wir sind hier im C Forum.

    In C braucht man es selten.
    In C++ nie.



  • BinSchonWeg schrieb:

    Aber ist das nicht der klassische Fall für eine Exception?

    Nein. Schon gar nicht in ANSI C.



  • BinSchonWeg schrieb:

    Aber ist das nicht der klassische Fall für eine Exception?

    deshalb wurden exceptions ja erfunden: damit die goto-gegner keine gotos benutzen müssen.



  • Eben, bevor man goto verwendet um aus ner tiefen Schleife zu springen, sollte man zur Exception greifen:

    struct ReturnFromLoop
    {};
    
    try
    {
     for(;;)
       while(bar.isActive()
           for(...)
           {
               if( foo.abort() )
                  throw ReturnFromLoop();
           }
    }
    catch( ReturnFromLoop& e )
    {
    }
    

    man beachte die Eleganz im Vergleich zu einem goto

    </ironie>



  • mit setjump / lonjmp...(#include <setjmp.h>) exceptionhandler

    mfg



  • Spezialfall: Wenn man das GCC-Feature "Jump table" benutzt, braucht man goto. Ist kein ANSI, hilft aber enorm, wenn man Performance braucht.


Anmelden zum Antworten