0 Proces zakończony kodem wyjścia zamiast powrotu do funkcji głównej

pytanie utworzone w Sat, Mar 16, 2019 12:00 AM

Tworzę system sklepu spożywczego jako zadanie w C dla klasy, którą odkładam do ostatniego roku. Używa połączonej listy do śledzenia produktów w sklepie. W większości przypadków działa, ale z jakiegoś powodu za każdym razem, gdy wybieram opcję menu, będzie działać, dopóki nie spróbuje uzyskać dostępu do NULL lokalizacji pamięci (Proces zakończył się kodem wyjścia -1073741819 (0xC0000005)) i zakończył z losową lokalizacją pamięci że próbował uzyskać dostęp, zamiast powracać do głównej funkcji.

Przetestowałem kilka różnych warunkowych pętli while, z których wszystkie kończą proces, ponieważ wygląda na to, że NULL jest dostępny nawet, jeśli warunek nie jest spełniony.

Program ma dwie klasy, z których obie znajdują się poniżej. Na razie staram się skupić na funkcji „showList”, ponieważ czuję, że jeśli uda mi się coś wymyślić, mogę poprawić pozostałe.

showList () jest wywoływany przez opcję 4 w menu.

#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
  1. Flushing input nie zawsze osiąga to, co myślisz. Musisz to zmienić. Może to być przyczyną twoich problemów, ale nie jest przenośne, więc nie mogę przetestować. Musisz.
    2019-03-16 19: 15: 26Z
  2. Dlaczego cursor->next jest NULL uniemożliwia drukowanie elementu?
    2019-03-16 19: 18: 30Z
  3. Należy go opróżnić z czegokolwiek, czego nie można było odczytać przy ostatniej próbie odczytu. Nie można tego jednak zrobić przez spłukiwanie. Albo musisz o tym wiedzieć wystarczająco dużo, abyś mógł je poprawnie zignorować (czytając, a potem nie używając), albo musisz przeczytać wszystko i dopiero TO to zinterpretować. Oto bardzo dobry, choć nieco cyniczny, brzmiący artykuł: sekrit .de /webdocs /c /beginners-guide-away-from-scanf.html
    2019-03-16 19: 22: 06Z
  4. Twój program się zawiesił, dlatego wykonanie zostało zatrzymane. Musisz rozwiązać ten problem. Czas odpalić debugera.
    2019-03-16 19: 24: 18Z
  5. @ NeilEdelman: Jest to ściśle zdefiniowana implementacja , a nie undefined .
    2019-03-16 20: 54: 32Z
0 Answers                              0                         
źródło umieszczone tutaj