简体   繁体   English

C - scanf 无需直接访问即可更改数组的值

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

It's my first time here on stackoverflow.这是我第一次来stackoverflow。 I hope my question fits.我希望我的问题适合。 We started programming C at the university this semester.我们本学期开始在大学编程 C。 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.这次我们应该编写一种 Hang-Man。 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.我不明白为什么会发生这种情况,因为 scanf 实际上并没有访问谜语。 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:( OUTPUT:抱歉没有图片,因为我没有 10 个代表:(

Link: https://imgur.com/UIeltVR链接: https://imgur.com/UIeltVR

// R3 in funktion uncoverLetter // 函数中的 R3 unlockLetter

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:您的问题出在createRiddle中,您在其中创建了***模式:

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. t只是数组temp的别名。)当 function 退出并因此无效时,该数组将超出 scope 。

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.当然,function 和调用者需要就必须提供多少空间达成一致。 (That could be another function parameter or a global constant.) (这可能是另一个 function 参数或全局常量。)

Allocate memory dynamically动态分配 memory

Dynamic memory is allocated on the heap and guaranteed not to be used by anyone else:动态 memory 在堆上分配,保证不被其他人使用:

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 Static arrays

Make the array static .制作数组static

    static char temp[laenge+1];

Here, the static keyword means that there is only one array that retains its value between calls.在这里, static关键字意味着只有一个数组在调用之间保留其值。 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.就好像您已将数组声明为 function 之外的全局数组,但另外它的名称只有您的 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.这是一个快速简单的解决方案,但是当您的 function 是递归的或当您的代码的其他部分使用相同的 function 时,它会失败。 (That's probably not the case in your game, though.) (不过,您的游戏中可能并非如此。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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