c-使用结构指针将字符串扫描到结构中

时间:2016-09-13 16:07:23

标签: c string pointers struct

我试图通过scanf()将字符串读入结构成员。 如果我启动这样的结构,它将编译并运行得很好:

    typedef struct list {
    char name[10];
    ...
    } List;

    List p;
    scanf("%s", p.name);
    printf("%s\n", p.name);

如果我通过指针启动结构,那么它仍然可以正常编译,但生成的程序崩溃了:

typedef struct list {

char name[10];
...
} List;

List *p;
scanf("%s", p->name);
printf("%s\n", p->name);

为什么会这样?

3 个答案:

答案 0 :(得分:1)

如果您将p声明为类型struct list,则会自动为其分配struct list的内存。您可以写入该内存,然后回读您已编写的内容,就像您在第一个示例中所做的那样。

如果您将p声明为类型struct list *,则会自动为其分配指针的内存。没有为struct list分配内存,部分原因是您可能实际上并不需要任何内存 - 您可能希望将指针指向指向通过其他方式分配的struct list。您可以写入指针并回读您所写的内容,但这不是您在第二段代码中尝试做的事情。您正在尝试写入和读取指针指向的内容,而指针的值仍然是不确定的。这会产生未定义的行为,程序崩溃是一个相当良性的例子。

如果你想使用指针,那么你有两个主要的选择:

  1. 将其指向现有的struct list
  2. List list;
    List *p = &list;
    
    scanf("%s", p->name);
    printf("%s\n", p->name);
    
    1. struct list动态分配内存,并在您完成后将其释放:
    2. List *p = malloc(sizeof *p);
      
      if (!p) {
          // handle allocation failure
      } else {
          scanf("%s", p->name);
          printf("%s\n", p->name);
          free(p);
      }
      

答案 1 :(得分:1)

这是sandipan's answer的C版本,因为它是用C ++编写的,你将它标记为C.

List *p = malloc(sizeof(List));
if(!p)
{
   //memory allocation failed, handle error here
}
scanf("%s", p->name); 
printf("%s\n", p->name);
//do stuff
free(p); //don't leak memory!

答案 2 :(得分:-1)

你需要在第二种情况下为指针(来自堆)分配内存才能使其工作(并在完成时删除分配给指针的内存,以防止内存泄漏)。在第一种情况下,在堆栈上创建局部变量。这是C ++版本:

typedef struct slist{ char name[10]; } SList; 
SList *p1 = (SList*)malloc(sizeof(SList)); 
scanf("%s", p1->name); 
printf("%s\n", p1->name);
free(p1);

这是C版:

{{1}}