C结构字段赋值覆盖另一个字段

C结构字段赋值覆盖另一个字段,c,struct,field,variable-assignment,C,Struct,Field,Variable Assignment,为了好玩,我正在写一个梦幻足球选秀节目 我遇到了一个奇怪的问题。我给一个struct字段分配了一个值,这会发生,但它也会将该值分配给struct中的另一个字段。为混乱的调试printf语句道歉 很明显,我对struct字段赋值有些不理解 代码: #include <stdio.h> #include <string.h> #include <stdlib.h> #define TRUE 1 int QB_count = 0; int RB_count =

为了好玩,我正在写一个梦幻足球选秀节目

我遇到了一个奇怪的问题。我给一个
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;
}

为什么
drafted.name
会变成“QB”?

get\u name
函数中,您正在为
struct Player
name
字段分配堆栈变量
name

在这方面:

drafted->name = name;
name
在函数中声明,因此其作用域仅限于该函数。一旦
get_name
返回,变量就超出范围,并尝试使用该内存调用未定义的行为

您需要使用
malloc
drafted->name
分配空间,并使用
strncpy
复制名称,而不是使用简单的赋值。如果可用
strdup
,您可以使用它来分配空间并在一个步骤中进行复制。或者,您可以在读取名称之前为
drafted->name
分配空间,并使用它代替
name
变量

作为最后一个选项,如果您假定名称的最大长度-您当前的代码允许名称的字符串长度不超过
19
-您只需为每个
struct Player
声明一个该大小的数组即可:

struct Player
{ 
    char name[NAME_MAXLEN];

get\u position
函数中,您的
position
字段存在相同的问题。

get\u name
函数中,您正在为
struct Player
name
字段分配堆栈变量
name

在这方面:

drafted->name = name;
name
在函数中声明,因此其作用域仅限于该函数。一旦
get_name
返回,变量就超出范围,并尝试使用该内存调用未定义的行为

您需要使用
malloc
drafted->name
分配空间,并使用
strncpy
复制名称,而不是使用简单的赋值。如果可用
strdup
,您可以使用它来分配空间并在一个步骤中进行复制。或者,您可以在读取名称之前为
drafted->name
分配空间,并使用它代替
name
变量

作为最后一个选项,如果您假定名称的最大长度-您当前的代码允许名称的字符串长度不超过
19
-您只需为每个
struct Player
声明一个该大小的数组即可:

struct Player
{ 
    char name[NAME_MAXLEN];

您在
get\u position
函数中的
position
字段也有相同的问题。

一般来说,
strncpy
不是您想要的(它的用处非常有限)。如果要复制字符串,最好使用
strlen
+
malloc
+
memcpy
。一般来说,
strncpy
不是您想要的(它的用处非常有限)。如果要复制字符串,最好使用
strlen
+
malloc
+
memcpy