【问题标题】:why scanf scans a null value为什么 scanf 扫描一个空值
【发布时间】:2014-09-10 12:35:33
【问题描述】:

在下面的代码中:

#include <stdio.h>

int main(){

  char *name;
  int age;  
  char *gen;

  printf("Your name:");
  scanf("%s",name);

  printf("Your age:");
  scanf("%d",&age);

  printf("Your gender:");
  scanf("%s",gen);

  printf("*****************\n");

  printf("%s is a %d years old %s \n",name,age,gen);

  return 0;  

}

当我这样运行它时:

Your name:tom
Your age:20
Your gender:male
*****************
tom is a 20 years old (null)

如您所见,gen 是一个空值,为什么scanf 读入 gen 失败而前两次读成功?

【问题讨论】:

  • 所以代替 char *name 使用 char name[20] 和 char gen[20]
  • @Rob 为什么name 不分配内存就可以工作,而gen 不行?
  • @user3289218 “运气”。未定义行为的最严重症状。
  • 你在鼻恶魔领域,任何事情都有可能发生。哦,你的代码中没有 null 值(或者至少,没有值保证为 null;在 Microsoft 调试环境中,保证 not 是)。
  • 是的,昆汀是对的。你很幸运,指向名称的指针没有指向重要的东西。你基本上写在内存中的某个地方,你可能已经写入了未分配的内存或在某处损坏了另一个变量或弄乱了函数的指令..没有办法知道。因此,您的代码行为未定义。

标签: c scanf


【解决方案1】:
char *name;
char *gen;

只是 char 指针,并没有指向任何内容。所以需要为其分配内存。

你可以为它分配内存

char *name = malloc(100);
char *gen  = malloc(100);

或定义具有预定义长度的字符数组

char name[100];
char gen[100];

【讨论】:

  • 你的意思是我需要指定char数组的长度,比如char name[10]
  • 为什么名称指针会起作用,我尝试先将scanf交换为读取gen,然后名称字符串变为空。
  • @ralph 这看起来是我未定义的行为。
  • 但是为什么要先给它分配内存呢?
  • @user3289218 因为这些只是指针,不指向任何地址。您必须首先给出指向该指针的地址指针,并使用该指针遍历内存为它分配多少。
【解决方案2】:
char *name;
char *gen;

是指针,需要改成数组

char name[256];//256 is arbitrary ofc
char gen[256];

或者用你的指针分配内存:

char *name = malloc(256 * sizeof(*name));
char *gen = malloc(256 * sizeof(*gen));

注意,如果你用malloc分配内存,检查分配是否失败是一个好习惯:

if (name == NULL)
    return -1;

【讨论】:

  • 无需输入mallocsizeof(char) 的强制类型转换返回始终1。所以不需要它。
  • 我认为强制转换 malloc 结果是一种习惯,这里也不需要 sizeof 但对于其他一切,因为 OP 似乎是 C 的新手,我不想让他感到困惑.但我会编辑更多解释
  • 但是为什么要先给它分配内存呢?
  • @mantal:您可能会考虑阅读此内容:stackoverflow.com/a/605858/694576 然后您可能同意许多人的观点,即强制转换 malloc 和朋友的结果实际上是一个坏习惯。
  • 关于sizeof(char)的冗余使用:这样做char * name = malloc(256 * sizeof(*name));是有道理的。
猜你喜欢
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 2021-10-27
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 2014-05-23
相关资源
最近更新 更多