0

I am trying to make a c program to join two link list But in the meanwhile when I was printing the data of the link list after every insertion the list is not printing I am hereby attaching the code

// Creating a menu deriv en program of single link list
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

struct node{
   int data;
   struct node *next;
};

void main()
{
   struct node *a;
   char ch;
   struct node *temp;
   struct node *temp1;
   a=NULL;
   clrscr();
   do
   {
      if(a==NULL)
      {
         temp=(struct node*)malloc(sizeof(struct node));
         printf("\nEnter Data\n");
         scanf("%d",&temp->data);
         temp->next=NULL;
         a=temp;
      }
      else
      {
         temp=(struct node*)malloc(sizeof(struct node));
         temp->next=NULL;
         printf("\nEnter data element\n");
         scanf("%d",&temp->data);
         temp1=a;
         while(temp1->next!=NULL)
         {
            temp1=temp1->next;
         }
         temp1->next=temp;
      }
      printf("\nDo You Wish to continue\n");
      ch=getch();
   }while(ch=='Y'||ch=='y');
   printf("Do You Wish To See More Link List Operations");
   ch=getch();
   if(ch=='Y'||ch=='y')
   {
      printf("Press 1 For inserting node at the beginning of the list");
      ch=getch();
      switch(ch)
      case 1:
         temp=(struct node*)malloc(sizeof(struct node));
         printf("Enter first data element");
         scanf("%d",&temp->data);
         temp1=(struct node*)malloc(sizeof(struct node));
         temp1=a;
         temp1=temp1->next;
         a=temp;
         temp=temp1;
   }

   printf("\nStatus of the link list\n");
   temp1=a;
   while(temp1!=NULL)
   {
      printf(" %d ",temp1->data);
      temp1=temp1->next;
   }
   getch();
}

Till now I have not written the code for joining two link list because first I want to get rid of this problem

Please Help!!!!

R Sahu
  • 204,454
  • 14
  • 159
  • 270
user6547375
  • 31
  • 1
  • 7
  • What excatly is problem ? It is not printing anything at all or not printing after every insertion ? – ameyCU Aug 22 '16 at 03:22
  • 1
    There's nothing that prints after every insertion. The code that prints the list contents is after the insertion loop. – Barmar Aug 22 '16 at 03:24
  • 1
    OT: Urgently learn how to factor your code into functions. To reduce repeating essentially the same code multiple times and to aid readability. – kaylum Aug 22 '16 at 03:28
  • after every insertion nothing is printing on the screen – user6547375 Aug 22 '16 at 04:05
  • See: [**Do I cast the result of malloc?**](http://stackoverflow.com/q/605845/995714). `temp = malloc (sizeof *temp);` is all that is required. – David C. Rankin Aug 22 '16 at 06:21
  • I am not getting where is the mistake in display function @DavidC.Rankin Please Help!!!! – user6547375 Aug 22 '16 at 14:27
  • I haven't gone through you code in detail, but if you attempt to insert a node at the beginning of the list, you appear to break the list. For an existing list, to insert at the beginning, following `scanf`, you would do `temp->next = a; a = temp;` there is no need to allocate or use `temp1` in that exchange. You simply point the `->next` pointer to the existing list `a` and then reassign `a = temp;` so that `a` points to the new first node. If your list is correct, your display will work. – David C. Rankin Aug 22 '16 at 16:22

3 Answers3

1

Errors that I see:

switch statement is not properly blocked

You have:

  switch(ch)
  case 1:
     temp=(struct node*)malloc(sizeof(struct node));
     printf("Enter first data element");
     scanf("%d",&temp->data);
     temp1=(struct node*)malloc(sizeof(struct node));
     temp1=a;
     temp1=temp1->next;
     a=temp;
     temp=temp1;

That is equivalent to:

  switch(ch)
  {
     case 1:
        temp=(struct node*)malloc(sizeof(struct node));
  }

  printf("Enter first data element");
  scanf("%d",&temp->data);
  temp1=(struct node*)malloc(sizeof(struct node));
  temp1=a;
  temp1=temp1->next;
  a=temp;
  temp=temp1;

I suspect you intended to use:

  switch(ch)
  {
     case 1:
        temp=(struct node*)malloc(sizeof(struct node));
        printf("Enter first data element");
        scanf("%d",&temp->data);
        temp1=(struct node*)malloc(sizeof(struct node));
        temp1=a;
        temp1=temp1->next;
        a=temp;
        temp=temp1;
  }

Wrong label in case

Since you are reading 1 into a char, you need to use:

    case '1':  // That is the character literal '1', not the integer literal 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

If you are exercising switch-case code. Operations in case statement are not correct.

....
case 1:
     temp=(struct node*)malloc(sizeof(struct node));
     printf("Enter first data element");
     scanf("%d",&temp->data);
     temp1=(struct node*)malloc(sizeof(struct node));
     temp1=a;
     temp1=temp1->next;
     a=temp;
     temp=temp1;
...

It needs to simply add a new node at the start of the list. Can do so by

case 1:
     temp=(struct node*)malloc(sizeof(struct node));
     printf("Enter first data element");
     scanf("%d",&temp->data);
     /*temp1=(struct node*)malloc(sizeof(struct node));
     temp1=a;*/
     temp->next = a;
     a=temp;
Rohan
  • 52,392
  • 12
  • 90
  • 87
0

You are absolutely going to pull your hair out mixing numeric and character input with scanf. getch is a non-portable bandaid that puts the keyboard in raw unbuffered mode that helps mask the problem, so you will do yourself a BIG favor if you simply learn how to handle user input correctly from the beginning.

The major drawback with scanf in taking mixed input is it leaves the '\n' in the input buffer. If you are only scanning numeric input, no problem because the numeric conversions skip leading whitespace (including the '\n'). However, the first time your ask for a character (e.g. 'y' or 'Y') BAM, scanf happily takes the '\n' waiting in the input buffer as your input. Further, you can't tell if a number or character has been correctly read throughout your code because you never check the return for scanf.

Rather than trying to duct-tape and bailing-wire your scanf input routine together into a working form, just do user input right. Read each input with fgets (which reads the '\n' and solves the problem) and use sscanf to parse the input. [1], e.g.

    if (a == NULL) {
        temp = malloc (sizeof *temp);
        temp->next = NULL;
        printf (" Enter Data: ");
        /* do NOT mix character and numeric input with scanf UNLESS
         * you know EXACTLY what your are doing.
         */
        if (!fgets (buf, MAXC, stdin)) {
            fprintf (stderr, "error: invalid input.\n");
            return 1;
        }
        if (sscanf (buf, "%d", &temp->data) != 1) {
            fprintf (stderr, "error: invalid conversion.\n");
            return 1;
        }
        a = temp;
    } ...

After your input is straightened out, you can concentrate on your logic errors with adding a value at the beginning of the list. As I pointed out in the comment, all that is needed is to create the new node, and set the ->next pointer to the existing list, and then set the list-address to that of the new node, e.g.:

    temp->next = a;
    a = temp;

Putting all those pieces together, and remembering to track and free the memory you have allocated, you could do something like the following with your code:

#include <stdio.h>
#include <stdlib.h>

#define MAXC 64   /* constant (macro define) to use for buffer length */

struct node {
    int data;
    struct node *next;
};

int main (void)             /* main is type 'int' and returns a value */
{
    char buf[MAXC] = "";    /* if taking numeric & char input use fgets */
    struct node *a = NULL, *temp, *temp1;
    // clrscr ();           /* clrscr is non portable, only win has conio.h */
    do {
        if (a == NULL) {
            temp = malloc (sizeof *temp);
            temp->next = NULL;
            printf (" Enter Data: ");
            /* do NOT mix character and numeric input with scanf UNLESS
             * you know EXACTLY what your are doing.
             */
            if (!fgets (buf, MAXC, stdin)) {
                fprintf (stderr, "error: invalid input.\n");
                return 1;
            }
            if (sscanf (buf, "%d", &temp->data) != 1) {
                fprintf (stderr, "error: invalid conversion.\n");
                return 1;
            }
            a = temp;
        } else {
            temp = malloc (sizeof *temp);
            temp->next = NULL;
            printf (" Enter data element: ");
            if (!fgets (buf, MAXC, stdin)) {
                fprintf (stderr, "error: invalid input.\n");
                return 1;
            }
            if (sscanf (buf, "%d", &temp->data) != 1) {
                fprintf (stderr, "error: invalid conversion.\n");
                return 1;
            }
            temp1 = a;
            while (temp1->next != NULL) {
                temp1 = temp1->next;
            }
            temp1->next = temp;
        }
        printf (" Do You Wish to continue (y/n)?: ");
        if (!fgets (buf, MAXC, stdin)) {
            fprintf (stderr, "error: invalid entry.\n");
            return 1;
        }
        // ch = getch ();    /* getch is non-portable */
    } while (*buf == 'y' || *buf == 'Y');

    printf (" Do You Wish To See More Link List Operations (y/n)? ");
    if (!fgets (buf, MAXC, stdin)) {
        fprintf (stderr, "error: invalid entry.\n");
        return 1;
    }
    if (*buf == 'y' || *buf != 'Y') {
        printf (" Press 1 For inserting node at the beginning of the list: ");
        if (!fgets (buf, MAXC, stdin)) {
            fprintf (stderr, "error: invalid entry.\n");
            return 1;
        }
        switch (*buf) {
            case '1' :  temp = malloc (sizeof *temp);
                        printf (" Enter first data element: ");
                        if (!fgets (buf, MAXC, stdin)) {
                            fprintf (stderr, "error: invalid input.\n");
                            return 1;
                        }
                        if (sscanf (buf, "%d", &temp->data) != 1) {
                            fprintf (stderr, "error: invalid conversion.\n");
                            return 1;
                        }
                        temp->next = a;
                        a = temp;
                        break;
            default :   fprintf (stderr, "error: invalid selection.\n");
        }
    }

    printf ("\nStatus of the link list\n");
    temp1 = a;
    while (temp1 != NULL) {
        printf (" %d ", temp1->data);
        temp1 = temp1->next;
    }
    putchar ('\n');
    // getch ();     /* use getchar, getch is non-portable */

    temp = a;
    while (temp) {   /* free the memory you have allocated */
        struct node *victim = temp;
        temp = temp->next;
        free (victim);
    }

    return 0;
}

Example Use/Output

$ ./bin/lldisplay
 Enter Data: 2
 Do You Wish to continue (y/n)?: y
 Enter data element: 3
 Do You Wish to continue (y/n)?: y
 Enter data element: 4
 Do You Wish to continue (y/n)?: y
 Enter data element: 5
 Do You Wish to continue (y/n)?: n
 Do You Wish To See More Link List Operations (y/n)? y
 Press 1 For inserting node at the beginning of the list: 1
 Enter first data element: 1

Status of the link list
 1  2  3  4  5

Look things over and make sure you understand it, and let me know if you have any questions.

footnotes:

1. you are not limited to only sscanf when parsing the line of text read as user-input, you can simply walk a pointer (or pair of pointers) down the string manually testing/parsing any combination of values you need. You can also use a pointer and walk the strtoX (e.g. strtol, strtoul, ...) functions down the line parsing numeric input as well (see man strtol and pay attention to the **endptr parameter). The key in the fgets/(then parse) approach is you decouple your read of input from the parsing of data allowing you to both (1) validate your read, and then also (2) validate your data rather than trying to do it all in one scanf call. There are uses for scanf, but taking alternating mixed character and numeric user-input isn't one of the recommended ones.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85