繁体   English   中英

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

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

这是我第一次来stackoverflow。 我希望我的问题适合。 我们本学期开始在大学编程 C。 不幸的是,只有少数在线讲座。 但我们仍然必须解决任务。

这次我们应该编写一种 Hang-Man。 换句话说,猜一个隐藏的单词。 我有以下问题。 我得到一个字符,但输入它后,谜语数组的内容发生了变化。 如果我省略输入,它会起作用。 我不明白为什么会发生这种情况,因为 scanf 实际上并没有访问谜语。 我自己不知道在这里做什么。 我希望有人能告诉我代码有什么问题。

//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:抱歉没有图片,因为我没有 10 个代表:(

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

// 函数中的 R3 unlockLetter

我强烈怀疑我犯了一个非常愚蠢的错误,但不幸的是我自己看不到/还看不到。 我期待着建议和帮助。

谢谢你。

您的问题出在createRiddle中,您在其中创建了***模式:

char* createRiddle(char const* const str){ 

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

    // ... create pattern ...

    return t;   
 }

您返回一个本地数组。 t只是数组temp的别名。)当 function 退出并因此无效时,该数组将超出 scope 。

有几种可能的解决方案。

让调用者提供空间

传入一个调用者可以填充的数组:

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

然后像这样调用它:

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

您不需要在这里返回数组,因为它与您提供的数组相同,只是填充了。 (如果它使调用更容易,你可以返回它。你也可以返回一个错误代码。使用你的良好判断力。)

当然,function 和调用者需要就必须提供多少空间达成一致。 (这可能是另一个 function 参数或全局常量。)

动态分配 memory

动态 memory 在堆上分配,保证不被其他人使用:

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

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

    return temp;
}

然后像这样使用它:

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

// ... play the game ...

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

Static arrays

制作数组static

    static char temp[laenge+1];

在这里, static关键字意味着只有一个数组在调用之间保留其值。 就好像您已将数组声明为 function 之外的全局数组,但另外它的名称只有您的 function 知道。

这是一个快速简单的解决方案,但是当您的 function 是递归的或当您的代码的其他部分使用相同的 function 时,它会失败。 (不过,您的游戏中可能并非如此。)

暂无
暂无

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

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