为了好玩,我正在编写一个梦幻足球选秀程序。
我遇到了一个奇怪的问题。我为 struct
字段分配了一个值,这发生了,但它也将该值分配给了 struct
中的另一个字段。为困惑的调试 printf
语句道歉。
我显然对 struct
字段赋值有些不理解。
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TRUE 1
int QB_count = 0;
int RB_count = 0;
int WR_count = 0;
int TE_count = 0;
int DEF_count = 0;
struct Player {
char *name;
char *position;
int age;
int bye_week;
};
int get_name (struct Player *drafted) {
char name[20];
fputs("Enter Player Name: ", stdout);
fflush(stdout);
if (fgets(name, sizeof name, stdin) != NULL){
char *newline = strchr(name, '\n');
if (newline != NULL){
*newline = '\0';
}
drafted->name = name;
printf("You've drafted: %s\n", drafted->name);
}
return 0;
}
int get_position(struct Player *drafted){
char position[20];
int depth;
char *nametemp = drafted->name;
printf("nametemp: %s\n", nametemp);
fputs("Enter Player Position in 'QB/RB/WR/TE/DEF' format: ", stdout);
fflush(stdout);
if (fgets(position, sizeof position, stdin) != NULL){
char *newline = strchr(position, '\n');
if (newline != NULL){
*newline = '\0';
}
drafted->position = position;
if (strcmp(position, "QB") == 0){
QB_count++;
depth = QB_count;
} else if (strcmp(position, "RB") == 0){
RB_count++;
depth = RB_count;
} else if (strcmp(position, "WR") == 0){
WR_count++;
depth = WR_count;
} else if (strcmp(position, "TE") == 0){
TE_count++;
depth = TE_count;
} else if (strcmp(position, "DEF") == 0){
DEF_count++;
depth = DEF_count;
} else {
printf("Please re-enter position information using the format 'QB' or 'qb'\n");
get_position(drafted);
return 0;
}
drafted->name = nametemp;
printf("NAME: %s\n", drafted->name);
printf("You've drafted %s at: %s%d\n", drafted->name, drafted->position, depth);
}
return 0;
}
int get_age (struct Player *drafted){
return 0;
}
int get_bye_week (struct Player *drafted){
return 0;
}
int main (){
int stop = 0;
char text[20];
while (TRUE){
struct Player drafted;
printf("Welcome to the 2012 Draft Day Program\n");
get_name (&drafted);
printf("NAME_MAIN: %s\n", drafted.name);
get_position(&drafted);
printf("You've drafted %s at: %s\n", drafted.name, drafted.position);
get_age(&drafted);
get_bye_week(&drafted);
fputs("Would you like to draft another player?\n"
"Enter '1' for no, '0' for yes\n", stdout);
fflush(stdout);
if(fgets(text, sizeof text, stdin)){
int number;
if (sscanf(text, "%d", &number) == 1){
if (number == 1){
printf("Draft Ended!\n");
break;
}
}
}
}
return 0;
}
结果输出是:
Welcome to the 2012 Draft Day Program
Enter Player Name: Aaron Rodgers
You've drafted: Aaron Rodgers
NAME_MAIN: Aaron Rodgers
nametemp: Aaron Rodgers
Enter Player Position in 'QB/RB/WR/TE/DEF' format: QB
NAME: QB
You've drafted QB at: QB1
You've drafted QB at: QB
Would you like to draft another player?
Enter '1' for no, '0' for yes
1
Draft Ended!
为什么 drafted.name
变成了“QB”?
最佳答案
在您的 get_name
函数中,您将分配给 struct Player
的 name
字段一个堆栈变量 name
.
在这一行中:
drafted->name = name;
name
是在函数中声明的,因此它的范围 仅限于该函数。一旦 get_name
返回,变量就会超出范围,并尝试使用该内存调用未定义的行为。
不是使用简单赋值,而是需要使用malloc
为drafted->name
分配空间,并使用strncpy
做一个名称的副本。如果 strdup
可用,您可以使用它来分配空间并一步完成复制。或者,您可以在读取名称之前为 drafted->name
分配空间,并用它代替 name
变量。
作为最后一个选项,如果您假设名称的最大长度 - 您当前的代码允许名称的字符串长度最大为 19
- 您可以简单地为每个 声明一个该大小的数组>结构播放器
:
struct Player
{
char name[NAME_MAXLEN];
get_position
函数中的 position
字段也有同样的问题。
关于C结构字段分配覆盖另一个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12024157/