2016-09-13 56 views
1

我想通过scanf()将字符串读入结构成员。 如果我发起这样一个结构,它会编译并运行就好:c-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); 

为什么会发生这种情况?

+1

你的malloc-ING P +您的直接问题看起来像一个空指针问题。 – Cody

+2

你需要初始化'p'指向某些有效的东西 - 一个本地或全局的'struct list'对象或动态分配的内存(例如通过'malloc()')。当你的代码站立时,'p'指向无效 - 它是未初始化的。 –

+1

您必须将您的编译器设置为产生最可能的警告并将它们视为错误。如果您使用的是常用命令行工具,请至少在编译命令中添加'-Wall -Werror'。如果你正在使用IDE,我不知道,也许会摆弄菜单。 –

回答

1

如果声明p作为struct list类型,然后为struct list存储器自动分配给它。你可以写入该内存,然后回读你写的内容,就像你在第一个例子中所做的那样。

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

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

  1. 它指向现有struct list
List list; 
List *p = &list; 

scanf("%s", p->name); 
printf("%s\n", p->name); 
  • 动态分配内存为struct list,并在完成时释放内存:
  • List *p = malloc(sizeof *p); 
    
    if (!p) { 
        // handle allocation failure 
    } else { 
        scanf("%s", p->name); 
        printf("%s\n", p->name); 
        free(p); 
    } 
    
    +0

    非常感谢你!当我启动一个指针时,我忘记了基本原则......我应该永远记得把一个新的指针指向某个东西。再次感谢!! – Zachary

    -1

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

    typedef struct list{ char name[10]; } List; 
    List *p = new List; 
    scanf("%s", p->name); 
    printf("%s\n", p->name); 
    delete p; 
    

    这里是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); 
    
    +3

    你应该使用malloc/free而不是new/delete,这个问题被标记为C而不是C++ – Cody

    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! 
    
    +1

    Thanks @PaulR,最近我一直在C中使用一个非常老的代码库,并且我已经习惯了随处可见的malloc转换。 – Cody

    +0

    非常感谢你! !这是一个非常粗心的错误,可以由像我这样的初学者... – Zachary

    +0

    @Zachary高兴地帮助。如果这回答您的问题,请单击答案旁边的复选标记以关闭问题。 – Cody