简体   繁体   English

在结构中分配字符串指针

[英]Assign a string pointer in a struct

I'm learning about C and having trouble with this.我正在学习 C 并且遇到了麻烦。 It does compile but the result is unexpected.它确实编译但结果出乎意料。 In my code, I have a struct:在我的代码中,我有一个结构:

typedef struct {
    char *title[50];
    float price;
} Book;

In the main, I am asking the user for number of books they want to have in the library.主要是,我问用户他们想在图书馆里有多少本书。 Then let them initialize the attributes of each book.然后让他们初始化每本书的属性。 Finally, print them out to the terminal using Display function.最后,使用Display function 将它们打印到终端。

void Display(Book* lib, int n);

int main() {
    int n;
    printf("Enter the number of books:\n" );
    scanf("%d", &n);
    if(n <= 0) {
        printf("Invalid number of book.");
        return 1;
    }

    Book *lib = (Book *) malloc(n * sizeof(Book));
    if(lib == NULL) {
        printf("The memory is full");
        return 1;
    }

    for(int i = 0; i < n; ++i) {
        char title[50];
        float price;
        printf("Book no.%d\n", i);
        printf("Book Title: ");
        scanf("%s", title);
        printf("Book Price: ");
        scanf("%f", &price);
        printf("\n");
        *(lib+i)->title = title;
        (lib+i)->price = price;
    }

    Display(lib, n);

    return 0;
}

The code compiles successfully, but the result is like this:代码编译成功,但是结果是这样的:

Enter the number of books:
2
Book no.0
Book Title: AAAA
Book Price: 1.0

Book no.1
Book Title: BBBB
Book Price: 9.9


----Displaying----
Book no.0
Book Title: BBBB
Book Price: $1.000000

Book no.1
Book Title: BBBB
Book Price: $9.900000

The title of the first book is wrong and it is the title of the second book.第一本书的书名不对,是第二本书的书名。 Why does this happen?为什么会这样? And how should I fix it?我应该如何解决它? Thank you谢谢

Edit : One of the requirements in my assignment is the title of Book must be of type char*编辑:我的作业中的要求之一是Book的标题必须是char*类型

Edit 2 : I realized my mistake when having 50 pointers of type char now.编辑 2 :当我现在有 50 个 char 类型的指针时,我意识到了我的错误。 How should I fix it?我应该如何修复它?

In your struct defintion:在您的结构定义中:

typedef struct {
    char *title[50];
    float price;
} Book;

You don't have an array of char (which can hold a string) but an array of pointers to char each of which can point to a string.您没有一个char数组(可以保存一个字符串),而是一个指向char的指针数组,每个指针都可以指向一个字符串。

Also, this doesn't do what you expect due to the definition of the price member:此外,由于price成员的定义,这不会达到您的预期:

*(lib+i)->title = title;

Change the definition to:将定义更改为:

typedef struct {
    char title[50];
    float price;
} Book;

And read directly into the struct fields instead of temp variables to avoid copying:并直接读入结构字段而不是临时变量以避免复制:

    printf("Book Title: ");
    scanf("%s", lib[i].title);
    printf("Book Price: ");
    scanf("%f", &lib[i].price);

Alternately, you can define title as a char * :或者,您可以将title定义为char *

typedef struct {
    char *title;
    float price;
} Book;

In which case you have to allocate space for the pointer to point to:在这种情况下,您必须为指向的指针分配空间:

    lib[i].title = malloc(50);
    printf("Book Title: ");
    scanf("%s", lib[i].title);

Note that you can't have it point to a local like you did before because that local goes out of scope at the end of the loop, making the pointer invalid.请注意,您不能像以前那样让它指向本地,因为本地在循环结束时会超出 scope,从而使指针无效。

If you have to use a pointer, you'll need to use dynamic allocation.如果必须使用指针,则需要使用动态分配。

The structure member should be declared as a pointer, not an array of pointers:结构成员应声明为指针,而不是指针数组:

typedef struct {
    char *title;
    float price;
} Book;

Then the loop should allocate memory for a copy of the title, and copy the title into it.然后循环应该为标题的副本分配 memory,并将标题复制到其中。

    for(int i = 0; i < n; ++i) {
        char title[50];
        float price;
        printf("Book no.%d\n", i);
        printf("Book Title: ");
        scanf("%s", title);
        printf("Book Price: ");
        scanf("%f", &price);
        printf("\n");
        (lib+i)->title = malloc(strlen(title)+1); // +1 for the trailing null
        strcpy((lib+i)->title, title);
        (lib+i)->price = price;
    }

Before you updated your post the declaration of the data member title of the structure在更新帖子之前,声明结构的数据成员title

typedef struct {
    char *title[50];
    float price;
} Book;

is incorrect (in the context of the program it does not make sense).是不正确的(在程序的上下文中它没有意义)。 The structure should look like结构应该看起来像

typedef struct {
    char title[50];
    float price;
} Book;

That is each book has one title and not 50 pointers to titles.也就是说,每本书都有一个标题,而不是 50 个标题指针。

And instead of this statement而不是这个声明

*(lib+i)->title = title;

you have to write at least like你必须至少写

#include <string.h>

//...

strcpy( ( lib+i )->title, title );

As for your output then you assigned the address of the same local variable title to the first pointer of the array至于您的 output 然后您将相同的局部变量标题的地址分配给数组的第一个指针

    char *title[50];

of each element of the dynamically allocated array.动态分配数组的每个元素。

Pay attention to that you should free the dynamically allocated memory when it is not used any more.请注意,您应该在不再使用动态分配的 memory 时释放它。 For example例如

free( lib );

Edit: One of the requirements in my assignment is the title of Book must be of type char*编辑:我的作业中的要求之一是书的标题必须是 char* 类型

After you updated your post then in this case the structure definition should look like更新帖子后,在这种情况下,结构定义应如下所示

typedef struct {
    char *title;
    float price;
} Book;

And you will need to allocate dynamically memory for entered title of an object of the structure.您需要为结构的 object 的输入标题动态分配 memory。

You could do it for example the following way.例如,您可以通过以下方式进行操作。 I suppose that you want to use pointers instead of the subscript operator.我想您想使用指针而不是下标运算符。

( lib + i )->title = malloc( strlen( title ) + 1 );
strcpy( ( lib + i )->title, title );

In this case before freeing the allocated array pointed to by the pointer lib you will need to free also each allocated character array like for example在这种情况下,在释放指针 lib 指向的分配数组之前,您还需要释放每个分配的字符数组,例如

for ( int i = 0; i < n; i++ )
{
    free( ( lib + i )->title );
}

free( lib );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM