Gavin
Gavin

Reputation: 2824

Input value to struct from scanf

I am trying to learn struct in C. The code complies fine, when I try to input a value, it crashes. I tried with an int member and it works.

typedef struct node{
    char *productName;
    int price;
    struct node *next;

}node;

int main (){
    node *head = (node*) malloc(sizeof(node));
    printf("Enter a product name: ");
    scanf("%s", &head->productName);
    printf("Product entered:%s",head->productName);
    //scanf("%d", &head->price); // this works
    //printf("Price entered:%d",head->price);

}

Upvotes: 1

Views: 2266

Answers (3)

Yogesh
Yogesh

Reputation: 25

Try this

scanf("%ms", &head->productName);

see how-can-i-read-an-input-string-of-unknown-length

may be this what you are looking for.

Upvotes: 0

Shivendra Mishra
Shivendra Mishra

Reputation: 688

Probably, You need to write it something like this:

/*Following code is not tested - Just a sample*/
typedef struct node{
    char *productName;
    int price;
    struct node *next;
}node;

int main (){
    node *head = (node*) malloc(sizeof(node));
    if( head == NULL ) 
     /*fail*/
    printf( "Size of product name:");
    scanf( "%d",&size);
    head->productName = malloc(size);
    if( head->productName == NULL ) {
       /*fail*/
    }
    printf("Enter a product name: ");
    scanf("%s", head->productName);
    printf("Product entered:%s",head->productName);
    /*scanf("%d", &head->price); // this works
      printf("Price entered:%d",head->price);*/

    /*Do stuff with node here*/
    free(head->productName);
    free(head);
    return 0;
}

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

The first problem, %s with scanf() expects a char * argument, what you're passing is a char **.

That said, even after correcting that (removing the &), head->productName is uninitialized and it does not point to a valid memory location. Accessing uninitilized memory invokes undefined behavior.

You need to make the pointer point to a valid memory before you can read from or write into it.

Finally, you should always check for the success of malloc() before using the returned pointer.

Combining all of them, something like

node *head = malloc(sizeof *head);
if (head) {
    head->productName = malloc(32); //some arbitary size
    if (head->productName) {
        printf("Enter a product name: ");
        scanf("%31s", head->productName);
        printf("Product entered:%s",head->productName);
    }
}

should do the job.


Note: A generic advice, don't forget to free() the returned pointer by memory allocator functions to avoid any possible memory leak, as your code grows bigger.

Upvotes: 2

Related Questions