【问题标题】:in a struct, scanf returns var address not value在结构中,scanf 返回 var 地址而不是值
【发布时间】:2016-06-20 18:27:35
【问题描述】:

我试图打印一个结构的 int 变量的值,但它却打印出地址。不知道为什么,代码如下:

struct data{
    char name[20];
    int age[100];
};

typedef struct data dataobj;

int main() {
    dataobj element;
    printf("enter a name:\n");
    gets(element.name);
    printf("name is: %s\n",element.name);
    printf("enter a number:\n");
    scanf("%d",&element.age);
    printf("number is: %d",element.age);
    return 0;
}

在这里输出:

enter a name:
John
name is: John
enter a number:
30
number is: 6356352
Process returned 0 (0x0)   execution time : 7.278 s
Press any key to continue.

你可以看到它没有像我想要的那样打印 30,而是打印 6356352(应该是 element.age var 的地址)

【问题讨论】:

  • 一个20字100岁的名字?
  • 是的,这是一个测试,忘记更改大小
  • 要将值读入数组的哪个元素?
  • 您可能想将结构中的年龄更改为 int age,为什么要将它作为一个数组?
  • 注意:永远不要使用gets!出于安全原因,它已从标准中删除。符合标准的实现应该警告缺少原型。在stdin 上使用fgets

标签: c struct scanf


【解决方案1】:

我不认为您的意思是将 age 属性作为 100 个 ints 的数组;如果您没有,如果您将struct 定义更改为只有一个int

struct data{
    char name[20];
    int age;
};

您提供的代码运行良好。如果您希望限制年龄的值,则不希望使用数组来这样做。使用这样的数组意味着每个 dataobj 都由一个名称和 100 个年龄来描述。相反,请考虑添加运行时检查,例如:

if (element.age < 0 || element.age > 99) {
    printf("Bad age value\n");
}

【讨论】:

  • 是的,现在它正在工作,我不知道为什么当我使用单个 var 时 CodeBlocks 一直崩溃,我尝试使用数组并且它工作但忘记更改代码.. 现在它不是崩溃了。欢呼
【解决方案2】:

不要使用gets,在 C99 中已弃用并从 C11 中删除

改为使用fgets:

char *ptr;

fgets(element.name, sizeof element.name, stdin);
/* Remove the trailing newline */
ptr = strchr(element.name, '\n');
if (ptr != NULL) {
    *ptr = '\0';
}

age 不是int 而是ints 的数组:

struct data{
    char name[20];
    int age[100];
};

改变

scanf("%d",&element.age);
printf("number is: %d",element.age);

scanf("%d",&(element.age[0]));
printf("number is: %d",element.age[0]);

为了读入年龄的第一个元素(位于索引 0 处),或者简单地使用普通的 int 而不是数组

【讨论】:

  • 好的,谢谢!实际上我把它搞砸了,并不是要创建一个数组,但如果我只是这样做: int Ages;程序崩溃了。
  • 我该如何替换gets?如果其中有空格,scanf 不会获取整个字符串
【解决方案3】:

在您的代码中考虑此语句。

scanf("%d",&element.age);

这里,age 的类型是数组,大小为 100 个整数元素。因此,在您的内存中创建了一系列 100 个整数,并且起始元素的地址存储在其他指针变量中(在您的情况下)。因此,当您扫描值时,您正在尝试操作数组的基地址,这是不可能的。这属于逻辑错误,只能通过理解来追踪。所以,只要记住一件事。

int age[100]

这是一个声明,编译器在其中创建一个指针和 100 个整数变量(连续)。并且第一个变量的地址存储在指针中,该指针采用数组的名称。

因此,当您尝试打印它时,它正在打印基地址数组 age[100]。

【讨论】:

    【解决方案4】:

    我认为您要做的是将年龄存储到年龄数组的第一个元素中:

    scanf("%d", element.age);
    printf("Age is %d\n", element.age[0]);
    

    基本上,有 99 个元素不会被使用。另一种方法是增加包含年龄的年龄数组中的值。换句话说,如果用户输入年龄 30 那么你基本上会做一个 element.age[29]++;

    通过这种方式,您可以将所有 100 个值保持为零,除了您想要提升的年龄(用户输入的年龄)

    另一件可能是好的做法是在使用 scanf 时使用单独的变量。比如这个代码片段:

    int incoming_age;
    scanf("%d", &incoming_age);
    element.age[0] = incoming_age;
    

    一旦您将输入扫描到incoming_age 变量中,您就可以用它做各种事情。它可以使代码更具可读性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多