0

I want to insert the data in ascending order based on the partNumber. When the function is called in main, then the node is successfully added at the first position. But on calling the function second time, there is some problem in insertion and I am unable to figure it out. When I enter the values(in second call), I get the error Process exited after 8.277 seconds with return value 3221225477

typedef struct part {
    int partNumber;
    char partName[200];
    int partQuantity;
    struct part *nextPart;
} Part;
Part *inventory = NULL;

void insertPart();

int
main(int argc, char *argv[])
{
    insertPart();
    insertPart();
    insertPart();
    insertPart();
    return 0;
}

void
insertPart()
{
    Part *tempPart,
    *traversePart,
    *swapPart;
    int counter = 0;

    traversePart = inventory;
    tempPart = (Part *) malloc(sizeof(Part *));

    printf("Enter the Part Number\n");
    scanf("%d", &(tempPart->partNumber));
    getchar();

    printf("Enter the Part Name\n");
    fgets(tempPart->partName, 200, stdin);

    printf("Enter the Part Quantity\n");
    scanf("%d", &(tempPart->partQuantity));
    getchar();

    if (inventory == NULL) {
        inventory = tempPart;
        printf("Part added at the first position.\n");
    }
    else {

        while (traversePart->nextPart->partNumber < tempPart->partNumber) {
            counter++;
            traversePart = traversePart->nextPart;
            if (traversePart->nextPart == NULL) {
                break;
            }
        }
        if (counter == 0) {
            swapPart = inventory;
            inventory = tempPart;
            tempPart->nextPart = swapPart;
        }
        else if (traversePart->nextPart == NULL) {
            traversePart->nextPart = tempPart;
        }
        else {
            swapPart = traversePart->nextPart;
            traversePart->nextPart = tempPart;
            tempPart->nextPart = swapPart;
        }
    }
    printf("Element added at position : %d", counter);
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • It seems you mean tempPart = (Part* ) malloc(sizeof(Part)); instead of tempPart = (Part* ) malloc(sizeof(Part*)); – Vlad from Moscow Mar 23 '21 at 20:35
  • The function declaration void insertPart(); shall be before main. – Vlad from Moscow Mar 23 '21 at 20:36
  • Thanks, but even after changing this, same problem persists – Ayush Narang Mar 23 '21 at 20:37
  • The timeout should be enough a hint that something went terribly wrong in the execution of your code. Because it's taking ~9 seconds to insert a second element in your list, it should be clear that something is wrong with the while loop. Try inserting breakpoints before/in/after the while loop and you'll be able to find the bug(s). – wLui155 Mar 23 '21 at 20:51
  • I guess the problem is with the condition in the while loop. But still trying to figure it out. – Ayush Narang Mar 23 '21 at 20:52
  • Well I guess this is a bit tricky, but the main hint is that the tail of your list has an uninitialized nextPart; it isn't guaranteed to be NULL. You need to figure out how to ensure that tail elements will have a next pointer of NULL. – wLui155 Mar 23 '21 at 20:55

2 Answers2

0

The problem is traversePart->nextPart->partNumber traversePart->nextPart is not referring to anything or it is not holding any of the address. When you insert first value if condition is true

if (inventory == NULL) {
    inventory = tempPart;
    printf("Part added at the first position.\n");
}

inventory now holding the address of tempPart but while assigning values of tempPart you never assign an address to its nextvalue and it's not there because you only inserted the first value. For the second position

else{
   while(traversePart->nextPart!=NULL)
      {
        traversePart=traversePart->nextPart;
      }
  if(traversePart->partNumber < tempPart->partNumber){
            //here you can verify conditions
         traversePart->nextPart = tempPart
      }
 }
Hamza Asif
  • 76
  • 8
0

You're intermixing fgets and scanf [and getchar]. Better to use just fgets and then apply strtol for numbers [or sscanf].

You're linked list code is a bit convoluted. It can be simplified.


Here's the refactored code. I've pulled some helper functions that I had lying around to do the prompting.

And, I added list printing.

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

typedef struct part {
    int partNumber;
    char partName[200];
    int partQuantity;
    struct part *nextPart;
} Part;
Part *inventory = NULL;

void insertPart();
int getstr(char *buf,int buflen,const char *prompt);
long getnum_strtol(const char *prompt);

int
main(int argc, char **argv)
{

    insertPart();
    insertPart();
    insertPart();
    insertPart();

    for (Part *cur = inventory;  cur != NULL;  cur = cur->nextPart)
        printf("partNumber=%d partQuantity=%d partName='%s'\n",
            cur->partNumber,cur->partQuantity,cur->partName);

    return 0;
}

void
insertPart(void)
{
    Part *tempPart;
    Part *cur;
    Part *prev = NULL;
    int counter = 0;

#if 0
    tempPart = (Part *) malloc(sizeof(Part *));
#else
    tempPart = malloc(sizeof(*tempPart));
#endif

    tempPart->partNumber = getnum_strtol("Enter the Part Number");
    getstr(tempPart->partName,sizeof(tempPart->partName),"Enter the Part Name");
    tempPart->partQuantity = getnum_strtol("Enter the Part Quantity");

    tempPart->nextPart = NULL;

    // find the tail/end of the list
    for (cur = inventory;  cur != NULL;  cur = cur->nextPart) {
        ++counter;

        // insert in sorted part order
        if (cur->partNumber > tempPart->partNumber)
            break;

        prev = cur;
    }

    do {
        tempPart->nextPart = cur;

        // insert in the middle or end of list
        if (prev != NULL) {
            prev->nextPart = tempPart;
            break;
        }

        // insert in new list or before first element of existing list
        tempPart->nextPart = inventory;
        inventory = tempPart;
    } while (0);

    printf("\nElement added at position : %d\n", counter);
}

// getstr -- get a string with prompt
// RETURNS: length or (<0 -> error)
int
getstr(char *buf,int buflen,const char *prompt)
{
    char *cp;
    int ret = 0;

    // NOTE: usage of the error codes in errno.h is arbitrary

    while (ret <= 0) {
        // ensure buffer has enough space
        if (buflen < 2) {
            ret = -ENOMEM;
            break;
        }

        // output prompt
        if (prompt != NULL) {
            printf("%s: ",prompt);
            fflush(stdout);
        }

        // get a line
        cp = fgets(buf,buflen,stdin);

        // EOF
        if (cp == NULL) {
            ret = -ENODATA;
            break;
        }

        // get buffer length
        ret = strlen(buf);

        // empty string
        if (ret <= 0)
            continue;

        // point to last char
        cp = &buf[ret - 1];

        // ensure we got a newline -- if not, fgets had to chop the line (i.e.)
        // the line is too long to fit in the buffer
        if (*cp != '\n') {
            ret = -ENOSPC;
            break;
        }

        // strip the newline -- we are done
        *cp = 0;
        --ret;
    }

    return ret;
}

// getnum_strtol -- get number using strtol
long
getnum_strtol(const char *prompt)
{
    int len;
    int readflg = 1;
    char *cp;
    char buf[100];
    long num = 0;

    while (readflg) {
        len = getstr(buf,sizeof(buf),prompt);

        if (len < 0)
            exit(1);

        num = strtol(buf,&cp,10);

        // ensure we got a least one digit
        if (cp <= buf)
            continue;

        switch (*cp) {
        case ' ':
        case '\t':
        case 0:
            readflg = 0;
            break;
        default:
            printf("getnum_strtol: not a valid number -- buffer '%s', invalid '%s'\n",
                buf,cp);
            break;
        }
    }

    return num;
}

Here's the input file I used to test:

37
Hex Bolt
12
28
Machine Screw
6
23
Brad Nail
1000
27
Lock Nut
300

Here's the program output:

Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 0
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 1
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 1
Enter the Part Number: Enter the Part Name: Enter the Part Quantity:
Element added at position : 2
partNumber=23 partQuantity=1000 partName='Brad Nail'
partNumber=27 partQuantity=300 partName='Lock Nut'
partNumber=28 partQuantity=6 partName='Machine Screw'
partNumber=37 partQuantity=12 partName='Hex Bolt'
Craig Estey
  • 30,627
  • 4
  • 24
  • 48