在我发布代码之前,我应该提到两件事,1有一个文本文件与该代码链接,我将在帖子中发布一些细节。 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;
}
}
}
答案 0 :(得分:1)
我可以在您的代码中看到一个问题 -
for(int t = 0; t < 5; t++){
if(strcmp(top[t].pl_name, pl[a].pl_name) == 0)
list = 1;
}
当您只设置p
时,您正在检查所有前5名。在检查第二个顶部时的含义,您正在检查当前名称是否存在于前5个中的任何一个。但是仅设置了1。
这会导致读取尚未初始化的内存(在strcmp
中)。很可能未初始化的名称不是以空字符结尾的字符串,因此会导致未定义的行为。
这是您的分段错误的原因。
这里的一个简单修复是将循环更改为 -
for(int t = 0; t < p; t++){
....
}
此外,您的topBalance
功能存在严重问题。您正在使用pl[i]
。但是i
永远不会被设置为任何东西。