进程以退出代码完成,而不是返回到主函数

时间:2019-03-16 19:13:38

标签: c linked-list

我正在创建一个杂货店系统,用C语言分配我推迟到大四的课程。它使用链接列表来跟踪商店中的产品。我已经使它工作了,但是由于某种原因,每次我选择一个菜单选项时,它将一直运行,直到它尝试访问一个NULL内存位置(进程以退出代码-1073741819(0xC0000005)完成)并以某个随机内存位置退出它试图访问而不是返回到主函数。

我已经测试了几种不同的while循环条件,所有这些条件都会导致该进程终止,因为即使不满足该条件,似乎也可以访问NULL。

该程序有两个类,两个都在下面。我现在正尝试着重于“ showList”功能,因为我觉得如果能够弄清楚,其余的我就可以纠正。

showList()由菜单上的选项4调用。

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

void displayMenu()
{
puts("Welcome to the LinkedList grocery store.");
puts("Please let me know what you want to do by typing in one of the 
numbers.");
puts("============================================================");
puts("1: Add product to store           2: Purchase product from store");
puts("3: Check price of a product       4: Show products in store");
puts("5: Remove a product from store        6: Find product");
puts("7: Inventory       8: Done for today");

}

int main(int argc, char *argv[])
{
product * head = NULL, *p;
char temp[N];
float sales = 0.0, quantity;
int choice, done = 0;
//system("cls");

  head = load(head, "inventory.txt");
  while (!done) {
    displayMenu();
    puts("What do you want to do?");
    fflush(stdin);
    scanf("%d", &choice);
    fflush(stdin);

    switch (choice)
    {
        case 1:
            head = addProduct(head);
            break;
        case 2:
            fflush(stdin);
            printf("Please enter the name of a product: ");
            fflush(stdin);
            scanf("%s", temp);
            fflush(stdin);
            printf("Please enter the quantity: ");
            fflush(stdin);
            scanf("%f", &quantity);
            fflush(stdin);
            sales += purchase(head, temp, quantity);
            break;
        case 3:
            fflush(stdin);
            printf("Please enter the name of a product: ");
            fflush(stdin);
            scanf("%s", temp);
            fflush(stdin);
            checkPrice(head, temp);
            break;
        case 4:
            showList(head);
            break;
        case 5:
            fflush(stdin);
            printf("Please enter the name of a product: ");
            fflush(stdin);
            scanf("%s", temp);
            fflush(stdin);
            rmItem(head, temp);
            break;
        case 6:
            fflush(stdin);
            printf("Please enter the name of a product: ");
            fflush(stdin);
            scanf("%s", temp);
            fflush(stdin);
            findProduct(head, temp);
            break;
        case 7:
            puts("****INVENTORY****");
            fflush(stdin);
            printf("Total sales: %f\n", sales);
            fflush(stdin);
            display(head);
            break;
        case 8:
            doneToday(head, "inventory.txt");
            done = 1;
            break;
        default:
            puts("Wrong code. Please try again.");
            break;
        }
    }

    return 0;
}

List.c:

#include "list.h"

// load in data from a file appending to the list l, return it
product * load(product *l, char fn[])
{
char name[N], quantity_unit[N], price_unit[N];
float quantity_value, price_value;

int rt;
product * head = l;
FILE * fin = fopen(fn, "r");

if(fin == NULL) {
    printf("InLoad: File open failed (%s)\n", fn);
    return NULL;
}

while (1) {
    rt = fscanf(fin, "%s %f %s %f %s\n", name, &quantity_value,quantity_unit, 
&price_value, price_unit );
    if (rt < 5)
        break;
    if (head == NULL)
        head = buildNode(name, quantity_value, quantity_unit, price_value, 
price_unit);
    else
        append(head, buildNode(name, quantity_value, quantity_unit, 
price_value, price_unit));
}
fclose(fin);
return head;
}

void doneToday(product* l, char fn[])
{
FILE * fout = fopen(fn, "w");
if(fout == NULL) {
    printf("InSave: File open failed (%s)\n", fn);
    return;
}
product* current = l;
while(current != NULL){
    fprintf(fout, "%s %f %s %f %s\n", current->name, current- 
>quantity_value,current->quantity_unit, current->price_value, current- 
>price_unit);
    current = current->next;
}

fclose(fout);

}

// build a product Node
product * buildNode(char name[], float quantity_value, char quantity_unit[], 
float price_value, char price_unit[])
{
product * p =  (product *) malloc(sizeof(product));
if(p == NULL) {
    puts("InBuildNode: Memory Allocation Failed!");
    return NULL;
}

strcpy(p->name, name);
p->quantity_value = quantity_value;
strcpy(p->quantity_unit, quantity_unit);
p-> price_value = price_value;
strcpy(p->price_unit, price_unit);

return p;
}

//shows the current product list
void showList(product *l)
{
product* cursor = l;
puts("************ Product List ******************");
printf("Name\tQuantity\tUnit\tPrice\t\tUnit\n\n");


    while(cursor != NULL){
        printf("%s\t%f\t%s\t%f\t%s\n", cursor->name, cursor->quantity_value, 
cursor->quantity_unit, cursor->price_value, cursor->price_unit);
        cursor = cursor->next;
    }


}

//adds a product to the list if it's not already
product * addProduct(product* l)
{
product* cursor = l;
product* result = l;
char name[N];
float quantity_value;
char quantity_unit[N];
float price_value;
char price_unit[N];

puts("Please enter the name of a product: ");
scanf("%s", name);
puts("Please enter the quantity value of a product: ");
scanf("%f", &quantity_value);
puts("Please enter the quantity unit of a product: ");
scanf("%s", quantity_unit);
puts("Please enter the price value of a product: ");
scanf("%f", &price_value);
puts("Please enter the price unit of a product: ");
scanf("%s", price_unit);

while(cursor != NULL){
    if(name == cursor->name){
        cursor->quantity_value += quantity_value;
        printf("The product with name **%s** already exists.", name);
        printf("The quantity was updated. New quantity is: %f", cursor- 
>quantity_value);
        return result;

    }
    cursor = cursor->next;

}

if(!cursor){
    result = append(l, buildNode(name, quantity_value, quantity_unit, 
price_value, price_unit));
    puts("New product added successfully!");
}

return result;

}

product * append(product *l, product * p)
{

product* cursor = l;

if(cursor == NULL){
    return p;

} else {

    while(cursor->next != NULL){
        cursor = cursor->next;
    }

    cursor->next = p;
    return l;
    }

}

void checkPrice(product* l, char p[])
{
product* cursor = l;

while(cursor->next != NULL){
    if(strcmp(cursor->name, p) == 0 ){
        printf("The current price of %s is %f %s", p, cursor->price_value, 
cursor->price_unit);
    }
    cursor = cursor->next;
    }
}

void findProduct(product* l, char p[])
{
product* cursor = l;

while(cursor->next != NULL){
    if(strcmp(cursor->name, p) == 0){
        printf("Product Found: %s %f %s %f %s", cursor->name, cursor- 
 >quantity_value, cursor->quantity_unit, cursor->price_value, cursor- 
 >price_unit);
        return;
    }
    cursor = cursor->next;
}

printf("The requested product was not found.");
}

void display(product *l)
{
product* cursor = l;

printf("Product: \n");
    while(cursor){
        printf("%s %f %s %f %s\n", cursor->name, cursor->quantity_value, 
cursor->quantity_unit, cursor->price_value, cursor->price_unit);
        cursor = cursor->next;

    }

}

float purchase(product* l, char p[], float q){
product* cursor = l;
float dollars = 0.0;

while(cursor->next != NULL){
    if(strcmp(cursor->name, p) == 0){
       if(cursor->quantity_value > q){
           dollars = cursor->price_value * q;
           cursor->quantity_value -= q;
           printf("Sale Completed, dollars made: %f\n", dollars);
           return dollars;
       } else if(cursor->quantity_value < q){
           dollars = cursor->price_value * cursor->quantity_value;
           printf("Sale partially completed, dollars made: %f\n", dollars);
           rmItem(l, cursor);
           return dollars;
       }
    }
}

printf("The sale was not completed, maybe the product doesn't exist.");
return dollars;

}

void rmItem(product* l, char p[])
{
product * current = l;
product * previous = current;
while(current != NULL) {
    if (strcmp(current->name, p) == 0) {
        if(previous == current)  // the first node
            l = (current->next);
        else // not the first one
            previous->next = current->next;

        free (current);
        return;
    }
    previous = current;
    current = current->next;
    }
}

list.h:

    #ifndef PROJECT3_LIST_H
#define PROJECT3_LIST_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 20

struct product
{
    char name[N];
    float quantity_value;
    char quantity_unit[N];
    float price_value;
    char price_unit[N];
    struct product *next;
};

typedef struct product product;

product * load(product *l, char fn[]);
product * buildNode(char name[], float quantity_value, char quantity_unit[], 
float price_value, char price_unit[]);
void showList(product *l);
product * addProduct(product* l);
product * append(product *l, product * p);
void checkPrice(product* l, char p[]);
void findProduct(product* l, char p[]);
void display(product *l);
float purchase(product* l, char product[], float q);
void rmItem(product* l, char p[]);
void doneToday(product* l, char fn[]);




#endif //PROJECT3_LIST_H

0 个答案:

没有答案