C语言的高级骰子游戏

Advanced Dice game in C

在我 post 代码之前,我应该提到两件事,1 有一个文本文件可以在 link 中使用这段代码,我将 post 一些细节在 post。 2,我的这个项目快完成了,所以我只真正关注 topFive() 函数和 topWin() 函数。但我的问题是,当我尝试在此函数中获得前五名玩家时,它只会打印出一个名字五次。非常感谢任何帮助,非常难过!

这是 players.txt 文件的内容,后面是代码。

Peter   100 90  
Emma    150 0   
Richard 50  10  
Abigail 138 128 
Jacob   210 100 
Anthony 800 -10 
Joseph  328 62  
Ashley  89  16  
Hannah  197 7   
Ethan   11  -20 



#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct { 
    char pl_name[10];
    int balance;
    int wincount;
} plyr;
plyr pl[10];
plyr top[5];
int psearch(){ // finds the index of the name in the file
    int i;
    char name[20];//This creates the initial array that searches throughout the array for the users name variable identity.
    printf("Enter the user's name. ");
    scanf("%s", name); // This will ask the user for the name whos balance they are changing.
    for(i=0;i<10;){
    if (strcmp(&name, pl[i].pl_name) == 0 ) break;
    i++; //This will continue the search.
    }
    return i;
}
void topBalance(){ // finds the top balance for 5 players
    int i;
    printf("What is the player name? ");
    scanf("%s", pl[i].pl_name); // This basically takes a users name and is ready to edit it.
    printf("What's the balance? ");
    scanf("%d", &pl[i].balance); // This changes whatever name is enters balance to whatever it wants to change it to.

}
void playGame(){ //Needs correction.
    srand(time(0));
    char enter = 'i'; 
    int r1, r2, sum, point;
    int playerno = psearch();
    char again = 'y';
    while (playerno == 10) { // This ensures that there are only 10 players that are going to be searched throughout.
        printf("Players not found.\n");
        playerno = psearch();   
    }
    while(again == 'y'){
        for(;;) {
            printf("Press enter to roll the dice. ");
            getchar(); // This will continue the dice to be rolled past the original point of just one or two rolls
            while (enter != '\n')
                enter = getchar();
            r1 = (rand() % 6) + 1; // This acts as the math of the function and it takes a random integer and divides it by 6 and takes the remainder by 1.
            r2 = (rand() % 6) + 1;
            sum = r1 + r2;
            printf("You got a %d and %d from the roll, the sum is %d. \n", r1, r2, sum);
            if(sum == 7 || sum == 11) {
                pl[playerno].balance += 10;
                pl[playerno].wincount += 10;
                printf("Your new balance is %d. \n", pl[playerno].balance);
                break;
            }
            else if(sum == 2 || sum == 3 || sum == 12){
                pl[playerno].balance -= 1; // This is anoyher simple way to lose if the sum is only equal to 2 or 3.
                pl[playerno].wincount -= 1;
                printf("You lose with a balance of %d", pl[playerno].balance);
                break; // The basic loss variable in the play game function.
                }
            else {
                point = sum;
                printf("Your point is %d. Roll %d without rolling a 7 to win. \n", point, point);
                for(;;){
                    enter = 'i'; 
                    printf("Roll the dice.\n");
                    while (enter != '\n') // This is a while loop that basically makes sure that if the dice is equal to 0 then it can not be submitted.
                        enter = getchar();
                    r1 = (rand() % 6) + 1;
                    r2 = (rand() % 6) + 1;
                    sum = r1 + r2; // Adds together the first and second random calculation above.
                    printf("You rolled %d and %d to get %d. \n", r1, r2, sum);
                    if(sum == point){
                        pl[playerno].balance += 10;
                        pl[playerno].wincount += 10;
                        printf("You win. New Balance is %d. \n", pl[playerno].balance);
                        break;
                    }
                    else if(sum == 7){
                        pl[playerno].balance -= 1;
                        pl[playerno].wincount -= 1;
                        printf("You lose. New Bal is %d. \n", pl[playerno].balance);
                        break;
                    }
                    else 
                        printf("Retry. \n");            
                }
                break;
            }
        }
    printf("Want to play again?");
    scanf("%s", &again);
    }
}

void topWin(){
int maxM, list, max1;
    for(int p = 0; p < 5; p++) {
        maxM = 999999;  //makes sure that the top maximum variable is a really high number in this loop, basically ensures that this loop will run as long as it doesn't go over 999999
        for(int a = 0; a < 10; a++){
            list = 0;
            for(int t = 0; t < 5; t++){
                if(strcmp(top[t].pl_name, pl[a].pl_name) == 0) list = 1;
                }
            if (pl[a].balance > maxM && !list) {
                maxM = pl[a].wincount;
                max1 = a;
            }
        }
        top[p] = pl[max1];
    }
    printf("\n");
    for(int a = 0; a < 5; a++) {
        printf("%s\t%d\n", top[a].pl_name, top[a].wincount);
    }
}
void topFive(){
int maxM, list, max1;
    for(int p = 0; p < 5; p++) {
        maxM = 999999;  //makes sure that the top maximum variable is a really high number in this loop, basically ensures that this loop will run as long as it doesn't go over 999999
        for(int a = 0; a < 10; a++){
            list = 0;
            for(int t = 0; t < 5; t++){
                if(strcmp(top[t].pl_name, pl[a].pl_name) == 0) list = 1;
                }
            if (pl[a].balance > maxM && !list) {
                maxM = pl[a].wincount;
                max1 = a;
            }
        }
        top[p] = pl[max1];
    }
    printf("\n");
    for(int a = 0; a < 5; a++) {
        printf("%s\t%d\n", top[a].pl_name, top[a].wincount);
    }
}
int main(){
    int i = 0, ch;
    FILE *rp;
    FILE *wp;
    rp = fopen("players.txt", "r");
    while(!feof(rp)){
        fscanf(rp, "%s\t%d\t%d", pl[i].pl_name, &pl[i].balance, &pl[i].wincount);
        i++;
}
    char name[10];
    srand (time(NULL));
    while (ch != 4) {
        printf("\n0. Top up your balance ");
        printf("\n1. Play Game!!! ");
        printf("\n2. Top 5 Players by Balance ");
        printf("\n3. Top 5 Winners! ");
        printf("\n4. Exit ");
        printf("\nWhat do you pick? ");
        scanf("%d", &ch);
        // From here on, I need to create seperate functions for each of these then tie them into the menu!!
        switch(ch) {
            case 0: 
                topBalance();
                wp = fopen("players.txt", "w");
                for(i = 0; i < 10; i++)
                    fprintf(wp, "%s\t%d\t%d\n", pl[i].pl_name, pl[i].balance, pl[i].wincount);
                fclose(wp);
                break;
            case 1: // Need to finish this and correct it!
                playGame();
                wp = fopen("players.txt", "w");
                for(i = 0; i < 10; i++)
                    fprintf(wp, "%s\t%d\t%d\n", pl[i].pl_name, pl[i].balance, pl[i].wincount);
                fclose(wp);
                break;                          
            case 2: // Segmentation Error
                topFive();
                break;
            case 3:
                topWin();
                break;
            case 4:
                break;

    break;      
    }
}
}

我可以看到您的代码存在一个问题 -

for(int t = 0; t < 5; t++){
    if(strcmp(top[t].pl_name, pl[a].pl_name) == 0) 
        list = 1;
}

您正在检查所有前 5 名,但只有 p 名已设置。这意味着当您检查第二个顶部时,您正在检查当前名称是否存在于前 5 个中的任何一个中。但只有 1 个已设置。

这导致读取未初始化的内存(在strcmp中)。很可能未初始化的名称不是以 nul 结尾的字符串,因此它会导致未定义的行为。

这就是您的分段错误的原因。

此处的一个简单解决方法是将循环更改为 -

for(int t = 0; t < p; t++){
    ....
}

此外,您的 topBalance 函数存在严重错误。您正在使用 pl[i]。但是 i 从未设置为任何值。