Speicherzugriffsfehler Anfängerproblem



  • Hallo,

    ich lerne gerade C und habe versucht ein Programm zu schreiben, dass die Fakultät einer einzugebenden Zahl berechnet. Das Programm besteht aus den Funktionen "einlesen()" und "fakultaet()". Probleme bereitet mir erste Funktion, und zwar, dann, wenn keine ganze positive Zahl eingegeben wurde. Das Programm soll dann abfragen, ob man die Eingabe wiederholen möchte. Egal was hier als Antwort eingegeben wird, beim Ausführen erscheint die Meldung: "Speicherzugriffsfehler". Was mache ich falsch?

    /*ue8_fakultaet*/
    /*berechnet die Fakultät einer einzugebenden Zahl*/
    
    #include <stdio.h>
    
    int i, m, k=1, check;
    int j;
    
    /*liest Zahl j ein*/
    void einlesen() {
    	while(m==0) {
    	printf("Bitte geben Sie eine ganze positive Zahl ein: ");
    	check = scanf("%u",&j);
    		if (check==0) {
    		printf("Die Eingabe war ungültig! Möchten Sie es nochmal versuchen? (j/n)\n");
    		char w;
    		scanf("%c",&w);
    			if (strcmp(w,'n')==0) {
    			printf("Das Programm wird abgebrochen.");
    			void exit();
    			}
    		}
    		else {
    		m=1;
    		}
    	}
    }
    
    /*berechnet Fakultät von Zahl j*/
    void fakultaet() {
    i=j;
    for (i<=j; i>1; i-=2) {
    	k=i*(i-1)*k;
    	}
    }
    
    int main () {
    einlesen();
    fakultaet();
    printf("Die Fakultät von %d ist %d.\n",j,k);
    return 0;
    }
    

    Ich bin für jede Hilfe dankbar! Viele Grüße, teresa.



  • teresa schrieb:

    int i, m, k = 1, check, j; // Globale Variablen sind furchtbar.
    
    void einlesen( void ) {
    	
    	while( m == 0 ) { // m ist nicht initialisiert -> Du vergleichst hier *irgendwas* mit 0.
    		
    		printf("Bitte geben Sie eine ganze positive Zahl ein: ");
    		check = scanf( "%u",&j );
            
    		if( check == 0 ) {
    			
    			printf("Die Eingabe war ungültig! Möchten Sie es nochmal versuchen? (j/n)\n");
    			char w;
    			scanf("%c",&w);
                
    			if( w == 'n' ) { // strcmp(w,'n') == 0 für chars brauchts kein strcmp.
    			
    				printf("Das Programm wird abgebrochen.");
    				void exit(); // <- ist kein Funktionsaufruf.
                }
            
    		} else {
    			m = 1; // hey cool, m bekommt endlich einen definierten Wert ;)
            }
        }
    }
    


  • Der Zugriffsfehler kommt daher, weil strcmp zwei Zeiger auf char erwartet, 'n' aber ein Zeichen ist (kein Zeiger).
    strcmp versucht nun auf die Adresse 'n' (was meist 0x0000006e ist) zuzugreifen.

    Du hast eine Funktionen (einlesen) und die können immer einen Wert zurückgeben.
    Nutze dies und verzichte auf globale Variablen.

    %u bei scanf ist für unsigned int da. D.h. die zugehörige Variable muss von dem Typ sein.
    Definiere j als unsigned int und du kannst dir die Überprüfung ersparen.

    Ach ja, nimm den C/C++ Button für deinen Code. Dann wird es auch farbig und bunt. 🙂



  • Vielen Dank schon mal!
    Aber es funktioniert immer noch nicht...
    Der Code schaut jetzt so aus!

    int i, m=0, k=1, check;
    int j;
    
    /*liest Zahl j ein*/
    void einlesen() {
    	while(m==0) {
    	printf("Bitte geben Sie eine ganze positive Zahl ein: ");
    	check = scanf("%u",&j);
    		if (check==0) {
    		printf("Die Eingabe war ungültig! Möchten Sie es nochmal versuchen? (j/n)\n");
    		char w;
    		scanf("%c",w);
    			if (w=='n') {
    			printf("Das Programm wird abgebrochen.");
    			exit(0);
    			}
    		}
    		else {
    		m=1;
    		}
    	}
    }
    

    Das Problem steckt irgendwie in dieser Sache mit dem Tastaturpuffer. Wie bekomme ich den leer? bzw. Ich habe alternativ versucht, statt

    scanf("%c",w);
    

    fgets() zu benutzen. Das klappt aber auch nicht...



  • teresa schrieb:

    scanf("%c",w);
    

    Ich kaufe gerne ein ' & '.

    j ist immer noch nicht unsigned .

    teresa schrieb:

    Das Problem steckt irgendwie in dieser Sache mit dem Tastaturpuffer. Wie bekomme ich den leer?

    Solange lesen, bis nichs mehr drinn ist.

    // edit: Unverbindliche Preisempfehlung:

    #include <stdio.h>
    #include <stdlib.h>
    
    unsigned long einlesen( void ) {
    
        unsigned long input = 0;
    	int ch = 0;
    
    	while( printf( "Bitte geben Sie eine ganze positive Zahl ein: " ), !scanf("%lu", &input ) ) {
    
    		while( ( ch = getchar() ) != '\n' && ch != EOF )
    			;
    
    		printf( "Die Eingabe war ungueltig! Möchten Sie es nochmal versuchen? (j/n)\n" );
    
    		if( getchar() == 'n' )
    			exit( EXIT_FAILURE );
    	}
    	return input;
    } 
    
    unsigned long fakultaet( unsigned long value ) {
    
    	unsigned long result = 1;
    	unsigned long i = 2;
    	for( ; i <= value; ++i ) {
    		result *= i;
    	}
    
    	return result;
    }
    
    int main( void )
    {
    	unsigned long input = einlesen();
    	printf( "Die Fakultaet von %lu ist %lu.\n", input, fakultaet( input ) );
    }
    


  • fgets will die Daten auch in einem char-Array speichern.

    Schau mal bei http://www.c-plusplus.net/forum/p1146014#1146014 nach.



  • Swordfish schrieb:

    teresa schrieb:

    int i, m, k = 1, check, j; // Globale Variablen sind furchtbar.
    
    void einlesen( void ) {
    	
    	while( m == 0 ) { // m ist nicht initialisiert -> Du vergleichst hier *irgendwas* mit 0.
    

    Quatsch.
    m ist sehr wohl initialisiert, und zwar mit 0, da globale Variable.



  • Danke fürs Wissenslückefüllen!



  • Swordfish schrieb:

    while( printf( "Bitte geben Sie eine ganze positive Zahl ein: " ), !scanf("%lu", &input ) ) {
    

    Das funktioniert natürlich so nicht, !scanf liefert auch bei EOF false bzw. true, was hier falsch ist. Auch wird der Eingabepuffer nur im Fehlerfall geleert, was nicht im Sinne des Anwenders sein dürfte.


Anmelden zum Antworten