Search code examples
cstructure

Why is this given C code not running properly?


I wrote this code that takes user input and then prints it out, but it's not working properly. It only recieves the name but not the age or salary of worker.

 #include <stdio.h>
 #include <stdlib.h>
struct worker
{
 char sri[100];
 int age;
 double salary;
  };
int main()
{
  struct worker *ptr;
 int n;
 printf("enter number of employy  ");
 scanf("%d", &n);
 //allocating memory for n ;
 ptr = (struct worker *)malloc(n * sizeof(struct worker));

 for (int i = 0; i < n; ++i)
 {

printf("For employee: %d \n ", i+1);
printf("Enter your name : ");
scanf("%s\n", (ptr + i)->sri);
printf("Enter salary:\n ");
scanf("%lf \n", (ptr + i)->salary);
printf("Enter age : \n");
scanf("%d \n", (ptr + i)->age);

 }

 
for (int i = 0; i < n; ++i)
{
 printf("Employee %d: ", i+1);
  printf("name =%s ", (ptr + i)->sri);
  printf("age = %d, ", (ptr + i)->age);
  printf("salary = %.2lf\n", (ptr + i)->salary);
 }
 free(ptr);

 return 0;
 }

Solution

  • There are several things to say about your program but let's start with the part that makes it fail - these two lines:

    scanf("%lf \n", (ptr + i)->salary);
    scanf("%d \n", (ptr + i)->age);
    

    (ptr + i)->salary is a double but here scanf requires a pointer to double

    (ptr + i)->age is an int but here scanf requires a pointer to int

    If you didn't get compiler warnings for this, you really need to increase the compilers warning level. For instance for gcc you should at least use -Wall -Werror. In that case you would have been told something like:

    main.cpp: In function 'main':
    main.cpp:36:10: error: format '%lf' expects argument of type 'double *', but argument 2 has type 'double' [-Werror=format=]
       36 | scanf("%lf \n", (ptr + i)->salary);
          |        ~~^      ~~~~~~~~~~~~~~~~~
          |          |               |
          |          double *        double
    main.cpp:38:9: error: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Werror=format=]
       38 | scanf("%d \n", (ptr + i)->age);
          |        ~^      ~~~~~~~~~~~~~~
          |         |               |
          |         int *           int
    cc1: all warnings being treated as errors
    

    which tells you it all !

    Other comments

    Always check the value returned by scanf - like:

    scanf("%d", &n); --> if (scanf("%d", &n) != 1) { // error handling }
    

    Don't put space or \n in the end of your scanf format string. It will give you unexpected behavior.

    When using %s in scanf always set a size limit.

    So:

    scanf("%s\n", --> scanf("%99s",
    

    Don't cast the value returned by malloc. So instead of

    ptr = (struct worker *)malloc(n * sizeof(struct worker));
    

    do

    ptr = malloc(n * sizeof(struct worker));
    

    or better

    ptr = malloc(n * sizeof *ptr);
    

    For better readability do

    (ptr + i)->age --> ptr[i].age
    

    So to get back to your original problem.

    Instead of:

    scanf("%d \n", (ptr + i)->age);
    

    do

    if (scanf("%d", &ptr[i].age) != 1) { exit(1); }