Need help in C programming linked list

Viewed 89

I'm creating a program using linked list which will later store in a text file. Basically this program will create an inventory, later update it as well. So I've successfully created the inventory (a function) and I've problem with updating it.

The inventory function is asking user to key in inputs, save into a text file and display it. The updating function has to select a particular item first and after that choosing whether to add or subtract the amount and the text file has to be updated at the same time.

So my problem is, I'm not able to compare the string input from the inventory function with this update function string input. Also, I need to receive an amount of item from user and then add the amount to the existing amount which I had entered in the inventory function earlier.

Visual Studio shows me that String 'code' might not be zero-terminated and String 'update' might not be zero-terminated for the update function.

I'm a beginner so I really need help from all of you, thank you!

This is the linked list codes:

struct donations
{
    char supplyName[100], supplyCode[20], donator[150];
    int no_ofShipment;
    float quantityReceived;
    struct donations* ptr;
} *start, *curr, *temp;

This is the inventory function (not a main function and will be changed later its a function for another main menu as the update function)

void main()
{
    void details();
    int i;
    FILE *fp;
    start = curr = NULL;

    curr = start;
    if (start == NULL)
    {
        start = curr = (struct donations *)malloc(sizeof(struct donations));

        for (i = 0; i < 5; i++)
        {
            curr = (struct donations *)malloc(sizeof(struct donations));

            details();

            if (i == 0)
                start = temp = curr;
            else
            {
                temp->ptr = curr;
                temp = curr;
            }
        }
        
        temp->ptr = NULL;
        temp = start;
        printf("\n\t Inventory Created Successfully!");     
        printf("\n\t Recorded to the end of the list!");
    }

    //create file & print output into the file

    if (fopen_s(&fp, "Donation.txt", "w") != 0)
    {
        printf("\nError");
        return;
    }
    if (!fp)
    {
        printf("\n Error in opening file!");
        //_getch();
        return;
    }

    curr = start;
    while (curr)
    {
        fprintf(fp, "%-30s", curr->supplyName);
        fprintf(fp, "%-30s", curr->supplyCode);
        fprintf(fp, "%-30s", curr->donator);
        fprintf(fp, "%10d", curr->no_ofShipment);
        fprintf(fp, "\t%.1f\n", curr->quantityReceived);
        curr = curr->ptr;
    }
    printf("\n\n\t File (records) has been created!");

    fclose(fp);
    
    // display output

    printf("\n\n\n\tDisplay Inventory");
    while (temp)
    {
        printf("\n\n\n\t Name of Supply: %-30s", temp->supplyName);
        printf("Supply Code: %-30s", temp->supplyCode);
        printf("Donator: %-30s", temp->donator);
        printf("No. of Shipment: %10d", temp->no_ofShipment);
        printf("\tQuantity Received: %.1f", temp->quantityReceived);
        temp = temp->ptr;
    }
}

void details()
{
    int i = 0;

    system("cls");
    printf("\tInventory Creation\t");

    printf("\n\n\tEnter Name of Supply: ",(i+1));
    gets_s(curr->supplyName);
    while (getchar() != '\n');

    printf("\n\tEnter Supply Code: ", (i + 1));
    gets_s(curr->supplyCode);
    while (getchar() != '\n');

    printf("\n\tEnter Donator: ", (i + 1));
    gets_s(curr->donator);
    while (getchar() != '\n');

    printf("\n\tEnter No. of Shipment: ", (i + 1));
    scanf_s("%d", &curr->no_ofShipment);
    while (getchar() != '\n');

    printf("\n\tEnter Quantity Received: ", (i + 1));
    scanf_s("%f", &curr->quantityReceived);
    while (getchar() != '\n');
}

this is my update function, but not finished yet.

void update_DonationQuantity()
{
    char code[10];
    char update[5];
    float quantity, Quantity;
    FILE *fp;

    printf("\n\tUpdate Donation Quantity\t\n");
    printf("\n\n\tSelect donation (CT/HS/FM/SM/OM): ");
    gets_s(code);

    if (strcmp(code, curr->supplyCode) == 0)
    {
        printf("\n\tReceived/Distibuted item (+/-): ");
        gets_s(update);
        while (strcmp(update, "+") && (update, "-") != 0)
        {
            printf("\n\tWrong input, Try Again");
            printf("\n\tReceived/Distibuted item (+/-): ");
            gets_s(update);
        }

        if (strcmp(update, "+") == 0)
        {
            printf("\n\t Enter received amount: ");
            scanf_s("%f", &quantity);
            
            if (fopen_s(&fp, "Donation.txt", "a") != 0)
            {
                printf("\nError");
                return;
            }
            if (!fp)
            {
                printf("\n Error in opening file!");
                //_getch();
                return;
            }

            curr->quantityReceived = quantity + curr->quantityReceived;
            fprintf(fp, "\t%.1f\n", curr->quantityReceived);
        }
    }
}
1 Answers

There are multiple problems in your code:

  • struct donations *ptr; is confusing: linked lists usually have a next member to chain the subsequent list element.

  • void main() is incorrect: the return type of main is int.

  • void details(); defining a function in a local scope, while allowed is very bad style. You should move this declaration before the start of the main function.

  • if (start == NULL) is always true.

  • start = curr = (struct donations *)malloc(sizeof(struct donations)); This line is useless and causes a memory leak: both curr and start are overwritten in the for loop just below.

  • if (!fp) is redundant: if fopen_s failed, it would have returned 0, otherwise fp must have been set to a valid pointer. Using fopen instead seems simpler and more portable.

  • printf("\n\n\tEnter Name of Supply: ",(i+1)); the (i+1) argument is useless. The same problem appears in the next printf statements.

  • gets_s(curr->supplyName); should have a size argument. You might be compiling as C++ for the compiler to accept this. Microsoft has a non-standard template with the same name as the C so call safe function gets_s they forcefully introduced into the C Standard. This is utmostly confusing. You should use fgets(), scanf() or a custom made function to read a string into the destination array, consuming the excess characters and the newline if present. gets_s does not do that, it behavior if the line entered is too long is obscure... The return value should be checked for errors.

  • while (getchar() != '\n'); is risky: if the stream reaches the end of file before reading a newline, this loop will get stuck in an infinite loop. Furthermore gets_s() should have read the newline, so this loop is only useful for the %d and %f conversions. For this case you could use a flush_stdin() function written this way:

      int flush_stdin(void) {
          int c;
          while ((c = getchar()) != EOF && c != '\n')
              continue;
          return c;
      }
    
Related