• C

Problem with single-linked list

extern"C" {
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
}

struct account
{
 char *name;
 //float cur_exp,prev_debit, prev_credit;
 struct account *next;
 };
typedef struct account acc;
display(acc *);
add(acc *);
int main()
{
int i;
clrscr();
acc *list_acc;
list_acc = NULL;
clrscr();
//Print the various options available to the user
printf("1. View the records\n");
printf("2. Calcuate current per head expenditure\n");
printf("3. View total expenditure till date\n");
printf("4. Who spends the most\n");
printf("5. Graphical representation\n");
printf("6. Add/Delete a member\n");
scanf("%d", &i);
switch(i)
 {
   case 1: printf ("Viewing records");
         add(list_acc);
         display(list_acc);
         break;

   case 2:
   case 3:
   case 4:
   case 5:
   case 6:
   default:
   printf("Input data unknown\n");
  };
getch();
}
display(acc *list_ptr)
 {
    while(list_ptr != NULL) //This is where the problem is
                      // the base address of the list still remains empty
                      // i.e. list_acc: {NULL, NULL}
    {
      printf("\n %s" ,list_ptr->name);
      list_ptr  = list_ptr->next;
     }
  }
add(acc *list_ptr) // this function works to the perfection.
 {
   acc *temp, *new_blk;
   temp = list_ptr;
   int i,number;
   printf(" Enter the number of people in your house");
   scanf("%d", &number);
   for(i=1;i<=number;i++)
   {
       if(list_ptr == NULL)
      {
       temp = (acc *)malloc(sizeof(acc));
       printf("\nEnter the name of person %d", i);
       scanf("%s",temp->name);
       temp->next = NULL;
       list_ptr = temp;
       }
      else
       {
        new_blk = (acc *)malloc(sizeof(acc));
        printf("\nEnter the name of person %d", i);
        scanf("%s",new_blk->name);
        new_blk->next = NULL;
        temp->next = new_blk;
       }

     }
   }

I reckon it's kind of local variable problem. However I am not able to exactly pin point the error. Kindly help. The program runs with out error but there is error in the functionality of the program. i.e. the display fucntion doesn't work.

Thnks

ksanand_beAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

brettmjohnsonCommented:
In fact, add() does not "works to the perfection".

The list_acc pointer in main() never gets modified to hold new nodes added to the list.
When add() updates list_ptr, it modifies the copy of the pointer that has been passed
on the stack as a function parameter.  This stack parameter goes out of scope as soon
as the function returns.  So effectively, you are always adding the "first node", then
forgetting it upon return from add().  There are couple of solutions to the problem:
Either have add() return the modified list, so main() can update the value:
      list_acc = add(list_acc);
or pass a pointer to the list (rather than a pointer to the list item) and add() will update
the pointer:
      add(&list_acc);


There are a couple of other problems with add().   Notice that the code paths for the
if-then-else clauses are nearly identical, differing only in where the newly allocated
node gets hooked into the list (head in then clause, tail->next in else clause).
Rather than duplicating the code to allocate the node, ask for name, and get the
answer for both code paths; delay the decision until later:

      new_blk = (acc *)malloc(sizeof(acc));
      printf("\nEnter the name of person %d", i);
      scanf("%s",new_blk->name);
      new_blk->next = NULL;
      if (list_ptr == NULL)
           list_ptr = new_blk;
      else
           temp->next = new_blk;

Better still, simply add new nodes to the head of the list, avoiding any conditional test at all.
      new_blk = (acc *)malloc(sizeof(acc));
      printf("\nEnter the name of person %d", i);
      scanf("%s",new_blk->name);
      new_blk->next = list_ptr;
      list_ptr = new_blk;

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ksanand_beAuthor Commented:
extern"C" {
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
}

struct account
{
 char *name;
 //float cur_exp,prev_debit, prev_credit;
 struct account *next;
 };
typedef struct account acc;
display(acc * );
acc add(acc *);
int main()
{
int i;
clrscr();
acc *list_acc;
list_acc = NULL;
clrscr();
//Print the various options available to the user
printf("1. View the records\n");
printf("2. Calcuate current per head expenditure\n");
printf("3. View total expenditure till date\n");
printf("4. Who spends the most\n");
printf("5. Graphical representation\n");
printf("6. Add/Delete a member\n");
scanf("%d", &i);
switch(i)
 {
   case 1: printf ("Viewing records");
         list_acc = add(list_acc);          // LINE 34
         display(list_acc);
         break;

   case 2:
   case 3:
   case 4:
   case 5:
   case 6:
   default:
   printf("Input data unknown\n");
  };
getch();
}
display(acc *list_ptr)
 {
    while(list_ptr != NULL)    {
      printf("\n %s" ,list_ptr->name);
      list_ptr  = list_ptr->next;
     }
  }
acc add(acc *list_ptr)
 {
   acc *temp, *new_blk;
   temp = list_ptr;
   int i,number;
   printf(" Enter the number of people in your house");
   scanf("%d", &number);
   for(i=1;i<=number;i++)
   {
        new_blk = (acc *)malloc(sizeof(acc));
        printf("\nEnter the name of person %d", i);
        scanf("%s",new_blk->name);
        new_blk->next = NULL;
        if(list_ptr == NULL)
         list_ptr = new_blk;
        else
         temp->next = new_blk;
       return (list_ptr);                            // LINE 75
       }


   }

As you told me I have made the changes but I get an error saying
"cannot convert account  to account * " line 34
"cannot convert account * to account"  line 75

Should I be returning list_ptr from the function add()??????

Thnks
0
ksanand_beAuthor Commented:
I tried using passing by reference and the program runs without any error. However only the first member and last member of the list are printed in the display function correctly. For instance if i input number = 4 (4 names -a,b,c,d) only a and d gets printed but the inbetween values r lost. kindly help. For your reference find the code below:

extern"C" {
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
}

struct account
{
 char *name;
 //float cur_exp,prev_debit, prev_credit;
 struct account *next;
 };
typedef struct account acc;
display(acc * );
acc add(acc **);
int main()
{
int i;
clrscr();
acc *list_acc;
list_acc = NULL;
clrscr();
//Print the various options available to the user
printf("1. View the records\n");
printf("2. Calcuate current per head expenditure\n");
printf("3. View total expenditure till date\n");
printf("4. Who spends the most\n");
printf("5. Graphical representation\n");
printf("6. Add/Delete a member\n");
scanf("%d", &i);
switch(i)
 {
   case 1: printf ("Viewing records");
         add(&list_acc);
         display(list_acc);
         break;

   case 2:
   case 3:
   case 4:
   case 5:
   case 6:
   default:
   printf("Input data unknown\n");
  };
getch();
}
display(acc *list_ptr)
 {
    while(list_ptr != NULL) //This is where the problem is
                      // the base address of the list still remains
                      // i.e. list_acc: {NULL, NULL}
    {
      printf("\n %s" ,list_ptr->name);
      list_ptr  = list_ptr->next;
     }
  }
acc add(acc **list_ptr)
 {
   acc *temp, *new_blk;
   temp = *list_ptr;
   int i,number;
   printf(" Enter the number of people in your house");
   scanf("%d", &number);
   for(i=1;i<=number;i++)
   {
        new_blk = (acc *)malloc(sizeof(acc));
        printf("\nEnter the name of person %d", i);
        scanf("%s",new_blk->name);
        new_blk->next = NULL;
        if(*list_ptr == NULL)
         {
         temp = new_blk;
         *list_ptr = temp;
        }
        else
         temp->next = new_blk;
       }

   }

Thankyou.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.