C 语言结构的简单地址簿程序

问题描述 投票:0回答:1

我有一个与此程序相关的问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct people
{
    char full_name [100];
    char age [100];
    char phone_number [100];

} Person;

typedef struct address
{
    Person *person_list;

} Address_book;

void print_person(const Person* person)
{
    printf("full_name    : %s \n", person->full_name);
    printf("age          : %s \n", person->age);
    printf("phone_number : %s \n", person->phone_number);
}

void getinput (char *string)
{
    ssize_t read = 0;
    char *line = NULL;
    size_t n = 0;
    read = getline (&line, &n, stdin);
    if (line[read - 1] == '\n')
        { line[read - 1] = 0; read--; }
    strncpy (string, line, read);
    if (line) free (line);
}

void create_address_book(Address_book* address_book)
{
    printf("insert full name   : ");
    getinput(address_book->person_list->full_name);
    printf("insert age         : ");
    getinput(address_book->person_list->age);
    printf("insert phone_number: ");
    getinput(address_book->person_list->phone_number);
}

int main()
{
Address_book* test = (Address_book*) malloc(sizeof(Address_book));
    create_address_book(&test);
    print_person(&test);

return 0;

}

它编译了,但是当我尝试运行该程序时,它给出了这样的结果:

你知道这个程序有什么问题吗?我对 C 结构和指针还是陌生的,所以我想获得一些帮助或者关于这个问题的一些解释。任何帮助将非常感激。

c pointers struct reference dereference
1个回答
0
投票

我按原样尝试了你的代码,编译器警告中列出了第一个暗示事情可能会不可预测的提示。

warning: passing argument 1 of ‘create_address_book’ from incompatible pointer type [-Wincompatible-pointer-types]|
note: expected ‘Address_book *’ {aka ‘struct address *’} but argument is of type ‘Address_book **’ {aka ‘struct address **’}|
warning: passing argument 1 of ‘print_person’ from incompatible pointer type [-Wincompatible-pointer-types]|
note: expected ‘const Person *’ {aka ‘const struct people *’} but argument is of type ‘Address_book **’ {aka ‘struct address **’}|
||=== Build finished: 0 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

启动该程序产生的结果与您所说的基本相同。

craig@Vera:~/C_Programs/Console/Addresses/bin/Release$ ./Addresses 
insert full name   : Craig
insert age         : 67
insert phone_number: 555-555-5555
full_name    : ��t�U 
age          : �U 
phone_number : �Lt�U 

问题在于代码试图传递“指向指针的指针”。

create_address_book(&test);

因此,在更正该问题之后,这突出显示了注释中提到的下一个问题,即地址结构具有未初始化的指针,导致段错误。

typedef struct address
{
    Person *person_list;

} Address_book;

craig@Vera:~/C_Programs/Console/Addresses/bin/Release$ ./Addresses 
insert full name   : Craig
Segmentation fault (core dumped)

为了提出最简单的解决方案,以便您的代码最初能够工作,我重构了“Address_book”结构的定义,以定义一个由 100 个“Person”结构组成的数组(100 是任意值)。

因此,重构的两个代码块是“Address_book”结构以及“main”函数内各个函数调用中指针使用的细化和修正。

typedef struct address
{
    // Person *person_list;         /* This is uninitialized and will cause issues */
    Person person_list[100];        /* A simple way to allocate the memory that will be needed */
} Address_book;

int main()
{
    Address_book* test = malloc(sizeof(Address_book));  /* Removed the qualifier as noted in the comments */
    create_address_book(test);                          /* test is already a pointer so no need for the ampersand in this case */
    //print_person(&test);                              /* The print function needs the pointer of the person varialbe and not the address pointer */
    print_person(test->person_list);                    /* Needed to refer to the pointer reference */

    return 0;
}

这导致了您想要实现的功能。

craig@Vera:~/C_Programs/Console/Addresses/bin/Release$ ./Addresses 
insert full name   : Craig
insert age         : 67
insert phone_number: 555-555-5555
full_name    : Craig 
age          : 67 
phone_number : 555-555-5555 

可能还有其他需要改进的地方,但请回顾一下这些重构,希望能帮助您理解指针的使用和内存分配。

© www.soinside.com 2019 - 2024. All rights reserved.