我正在创建一个杂货店系统,用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