简体   繁体   中英

C - scanf changes the values ​of an array without direct access

It's my first time here on stackoverflow. I hope my question fits. We started programming C at the university this semester. Unfortunately there are only a few online lectures. But we still have to solve the tasks.

We should program a kind of Hang-Man this time. In other words, guess a hidden word. I have the following problem. I get a char, but after entering it, the contents of the riddle array change. If I leave out the input it works. I don't understand why this happens because scanf doesn't actually access riddle. I myself don't know what to do here. I hope someone can tell me what's wrong with the code.

//sry some variables and texts are in german
char* createRiddle(char const* const str){ 

    int laenge = strlen(str);
    char temp[laenge+1];
    char *t = temp;
    strcpy(temp, str);
    int te = strcmp(temp, str);     
    if (te != 0){
    printf("ERROR: Bei der Speicherreservierung ist ein Fehler aufgetreten");
        exit(0);
    }
    int i;
    for (i=0; i < (int)strlen(temp);i++){
        if (str[i] > 65 && str[i] < 90){ //ASCII Großbuchstaben-Bereich prüfen 
            char verdeckt = '*';
            temp[i] = verdeckt;
        } else {
            temp[i] = str[i];
        }
    }

    return t;


 }

//----------------------------
int uncoverLetter(char *riddle, const char *solution, char letter){ 
    printf("RD3: %s\n",riddle);
    letter = toupper(letter);

    int i; 
    int treffer = 0;
    for (i=0; i < (int)strlen(solution); i++) {

        if (letter == solution[i]) { // Buchstabe im Wort?
            if (letter != riddle[i]) { //Buchstabe schon aufgedeckt?
                riddle[i] = solution[i];
                treffer = treffer + 1;
            }
        }

    }
    return treffer; 
}

//----------
int gamingLoop(const char* solution){ 

    int punkte;  //points
    printf("Lets GO!\n\n"); 
    char *riddle = createRiddle(solution);
    printf("Gesuchtes Wort: %s\n\n",riddle); //Word: *-******* ( = C-Compiler )
    int highscore = 0;

 while ((strcmp(riddle, solution)) != 0) {

        printf("RD1: %s\n",riddle);  //Test: What does Riddle look like?
        printf("Bitte geben Sie einen Buchstaben ein: "); // pls enter letter
        char eingabe; 
        scanf(" %c", &eingabe);  //-----!!Here is the point where things go wrong!!------
        printf("RD2: %s\n",riddle); //Test2
        int treffer = uncoverLetter(riddle, solution, eingabe);


        //----------- probably unimportant for the problem ----------------

        //Zufallszahl 

        int zufz = (rand() % 11) + 1;
        int ii = 1;
        for (ii=1; ii < 11 ; ii++){
            if ( zufz == ii) {
            punkte = zufz*100;
            }
        }
        //------------
        if (treffer != 0) {
            printf("Du hast %d richtige Treffer.\n", treffer);
            highscore = highscore + (treffer*punkte);
            printf("Punkte: %i\n\n", highscore);
        } else {
            printf("Du hast leider keinen Treffer.\n");
            highscore = highscore - punkte; 
            printf("Punkte: %d\n\n", highscore);
        }
        printf("%s\n\n",riddle);
    }

    return highscore;

}



OUTPUT: Sry no pic because i dont have 10 rep:(

Link: https://imgur.com/UIeltVR

// R3 in funktion uncoverLetter

I strongly suspect that I made a very stupid mistake, but unfortunately I can't see it myself / can't see it yet. I look forward to advice and help.

Thank you.

Your problem is in createRiddle , where you create the *** pattern:

char* createRiddle(char const* const str){ 

    int laenge = strlen(str);
    char temp[laenge+1];
    char *t = temp;

    // ... create pattern ...

    return t;   
 }

You return a local array. ( t is just an alias to the array temp .) That array will be out of scope when the function exits and therefore invalid.

There are several possible solutions.

Make the caller provide space

Pass in an array that the caller can fill:

void createRiddle(char *temp, char const* const str)
{ 
    // ... create pattern in temp ...
 }

Then call it like this:

char riddle[MAX];
createPattern(riddle, solution);

You don't need to return the array here, because it is the same array you provided, only filled. (You could return it if it makes calling easier. You could also return an error code. Use your good judgement.)

Of course, the function and caller need to agree how much space must be provided. (That could be another function parameter or a global constant.)

Allocate memory dynamically

Dynamic memory is allocated on the heap and guaranteed not to be used by anyone else:

char *createRiddle(char const* const str)
{ 
    int laenge = strlen(str);
    char *temp = malloc(laenge + 1);

    // ... create pattern in temp ...

    return temp;
}

Then use it like this:

char *riddle = createRiddle(char const* const str);

// ... play the game ...

free(riddle);  // be nice and clean up

Static arrays

Make the array static .

    static char temp[laenge+1];

Here, the static keyword means that there is only one array that retains its value between calls. It is really as if you has declared the array as global outside the function, but with the addition that its name is only known to your function.

That's a quick and easy solution, but it fails when your function is recursive or when other parts of your code use the same function. (That's probably not the case in your game, though.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM