简体   繁体   中英

Assign a string pointer in a struct

I'm learning about C and having trouble with this. 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.

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*

Edit 2 : I realized my mistake when having 50 pointers of type char now. 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.

Also, this doesn't do what you expect due to the definition of the price member:

*(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 * :

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.

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.

    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

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.

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

    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. For example

free( lib );

Edit: One of the requirements in my assignment is the title of Book must be of type 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.

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

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

free( lib );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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