簡體   English   中英

我的指針和結構代碼顯示垃圾值

[英]My pointers and struct code is displaying garbage values

目前,我正在嘗試創建一個包含商店產品庫存的程序。 我已經能夠創建一個允許用戶在結構數組中輸入新項的函數,但是當我嘗試打印值時,我得到了垃圾值。 (請忽略switch語句,因為代碼正在進行中)。

#include <stdio.h>
#include <stdlib.h>
#define MAX_INVENTORY_SIZE 100

typedef struct {
    char item_Number[3];
    char item_Name[20];
    float item_Profit;
    float latest_Price;
    unsigned int stock;
    unsigned int total_Sold;
    struct InventoryItemType *next;
}InventoryItemType;
void MainMenu();
void displayInventory(InventoryItemType *(*));
void addItem(InventoryItemType, int i);

int main()
{
    int i=1;
    char selection;
    int count=1;
    InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE] ;

    inventoryItems[0]=NULL;
    while(1)
    {
        MainMenu();
        scanf(" %c", &selection);
        switch(selection) 
        {
        case 'A' :
            displayInventory(inventoryItems);
            break;
        case 'B' :
        case 'C' :
            inventoryItems[count]= (InventoryItemType*)malloc(sizeof(InventoryItemType));
            addItem(*inventoryItems[count], count);
            continue;
        case 'D' :
        case 'E' :
        case 'F' :
        case 'G' :
        case 'H' :
        default :
            printf("Invalid\n" );
        }
        printf("Bottom of code\n");
        system("pause");
    }
}
void MainMenu()
{
    printf("A. Display Inventory\n");
    printf("B. Display Sales\n");
    printf("C. Add Item\n");
    printf("D. Remove Item\n");
    printf("E. Enter Shipment\n");
    printf("F. Update Sales\n");
    printf("G. Sort\n");
    printf("H. Exit\n");
    printf("Make a selection\n");
}
void displayInventory(InventoryItemType *display)
{
    int i;
    for(i=0; i<MAX_INVENTORY_SIZE; i++)
    {
        printf("Name:%s\n", display[i].item_Name);
        printf("Stock:%d\n", display[i].stock);
        printf("Price:%.2f\n", display[i].latest_Price);
        printf("Total Value:%.2f\n", (display[i].stock)*(display[i].latest_Price));
        printf("\n");
    }
}
void addItem(InventoryItemType display)
{

    printf("\nEnter details of item \n\n");
    printf("Enter Item Name: \n");
    scanf("%s", display.item_Name);
    printf("\nEnter Item no: \n");
    scanf("%s", display.item_Number);

    printf("\nEnter Stock: \n");
    scanf("%d", &display.stock);

    printf("\nPurchase Price: \n");
    scanf("%f", &display.latest_Price);
}

更新

我嘗試應用所有答案(通過一系列試驗和錯誤)並提出了這段代碼。 我目前有正確接受新項目並顯示該項目的代碼,但在添加更多項目后會崩潰(如果我繼續通過錯誤,我會得到垃圾顯示值)。 我很確定它與我通過malloc分配內存的方式有關。 我的目標是在初始化值之前使用malloc為項創建空間。

編輯代碼:

#include <stdio.h>
#include <stdlib.h>
#define MAX_INVENTORY_SIZE 100

typedef struct {
    char item_Number[4];
    char item_Name[20];
    float item_Profit;
    float latest_Price;
    float selling_Price;
    unsigned int stock;
    unsigned int total_Sold;
}InventoryItemType;
void MainMenu();
void displayInventory(InventoryItemType *, int);
void displaySales(InventoryItemType *, int);
InventoryItemType *addItem(InventoryItemType *, int);

int main()
{
    int i=0, item_count=0;
    char selection;
    InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE];
    while(1)
    {
        MainMenu();
        scanf(" %c", &selection);
        switch(selection) 
        {
        case 'A' :
            displayInventory(*inventoryItems, item_count);
            break;
        case 'B' :
            displaySales(*inventoryItems, item_count);
            break;
        case 'C' :
            inventoryItems[item_count]=(InventoryItemType*)malloc(sizeof(InventoryItemType));
            inventoryItems[item_count]=addItem(inventoryItems[item_count],item_count);
            item_count++;
            continue;
        case 'D' :
        case 'E' :
        case 'F' :
        case 'G' :
        case 'H' :
        default :
            printf("Invalid Entry\n" );
            system("pause");
        }
        system("cls");
    }
}
void MainMenu()
{
    printf("A. Display Inventory\n");
    printf("B. Display Sales\n");
    printf("C. Add Item\n");
    printf("D. Remove Item\n");
    printf("E. Enter Shipment\n");
    printf("F. Update Sales\n");
    printf("G. Sort\n");
    printf("H. Exit\n");
    printf("Make a selection\n");
}
void displayInventory(InventoryItemType *display, int key)
{
    if(display[0].item_Name == NULL)
    {
        printf("No stock");
        system("pause");
    }
    else
    {
        int i;
        for(i=0; i<key; i++)
        {
            printf("Item No.:%s\n", display[i].item_Number);
            printf("Item Name:%s\n", display[i].item_Name);
            printf("Item Stock:%d\n", display[i].stock);
            printf("Item Purchased Price:%.2f\n", display[i].latest_Price);
            printf("Total Value of Items:%.2f\n", (display[i].stock)*(display[i].latest_Price));
            printf("\n");
            system("pause");
        }
    }
}
void displaySales(InventoryItemType *display, int key)
{
    int i;
    float total_profit=0;
    for(i=0; i<key; i++)
    {
        printf("Item No.:%s\n", display[i].item_Number);
        printf("Item Name:%s\n", display[i].item_Name);
        printf("Number of Item Sold:%d\n", display[i].total_Sold);
        printf("Item Selling Price:%.2f\n", display[i].selling_Price);
        printf("Total Profit from Item:%.2f\n", (display[i].selling_Price-display[i].latest_Price)*display[i].total_Sold);
        total_profit=total_profit+((display[i].selling_Price-display[i].latest_Price)*display[i].selling_Price);
        if(i==key)
        printf("Total Over-all Profit:%.2f", total_profit);
        system("pause");
    }
}
InventoryItemType *addItem(InventoryItemType *change, int key)
{
    InventoryItemType *current= (InventoryItemType*)malloc(sizeof(InventoryItemType));
    printf("\nEnter details of item \n\n");
    printf("Enter Item no: \n");
    scanf("%s", current[key].item_Number);
    printf("Enter Item Name: \n");
    scanf("%s", current[key].item_Name);
    printf("Enter Stock: \n");
    scanf("%d", &current[key].stock);
    printf("Enter Purchase Price: \n");
    scanf("%f", &current[key].latest_Price);
    current[key].selling_Price=(current[key].latest_Price)*1.5;
    current[key].total_Sold=0;
    change=current;
    system("cls");
    return change;
}

存在許多錯誤/沖突。 單獨評論太多了。 我已經注釋並更正了代碼,顯示了錯誤以及之前/之后。 還有更多的工作要做,但這應該讓你更接近。

#include <stdio.h>
#include <stdlib.h>
#define MAX_INVENTORY_SIZE 100

typedef struct {
    char item_Number[3];
    char item_Name[20];
    float item_Profit;
    float latest_Price;
    unsigned int stock;
    unsigned int total_Sold;
    struct InventoryItemType *next;
} InventoryItemType;

void MainMenu();

#if 0
void displayInventory(InventoryItemType *(*));
#else
void displayInventory(InventoryItemType *,int);
#endif

#if 0
void addItem(InventoryItemType, int i);
#else
void addItem(InventoryItemType *);
#endif

int main()
{
    int i=1;
    char selection;

    // NOTE/BUG: starting at 1 will leave item 0 undefined
#if 0
    int count=1;
#else
    int count=0;
#endif

    // better to do this with a stack array than pointers to malloc'ed items
#if 0
    InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE] ;
#else
    InventoryItemType inventoryItems[MAX_INVENTORY_SIZE] ;
#endif

#if 0
    // NOTE/BUG: this will segfault because inventoryItems is undefined here
    inventoryItems[0]=NULL;
#endif

    while (1) {
        MainMenu();
        scanf(" %c", &selection);
        switch(selection) {
        case 'A' :
#if 0
            displayInventory(inventoryItems);
#else
            displayInventory(inventoryItems,count);
#endif
            break;
        case 'B' :
        case 'C' :
#if 0
            inventoryItems[count]= (InventoryItemType*)malloc(sizeof(InventoryItemType));
            addItem(*inventoryItems[count], count);
#else
            addItem(&inventoryItems[count]);
            count += 1;
#endif
            continue;
        case 'D' :
        case 'E' :
        case 'F' :
        case 'G' :
        case 'H' :
        default :
            printf("Invalid\n" );
        }
        printf("Bottom of code\n");
        system("pause");
    }
}

void MainMenu()
{
    printf("A. Display Inventory\n");
    printf("B. Display Sales\n");
    printf("C. Add Item\n");
    printf("D. Remove Item\n");
    printf("E. Enter Shipment\n");
    printf("F. Update Sales\n");
    printf("G. Sort\n");
    printf("H. Exit\n");
    printf("Make a selection\n");
}

#if 0
void displayInventory(InventoryItemType display)
{
    int i;
    for(i=0; i<MAX_INVENTORY_SIZE; i++)
    {
        printf("Name:%s\n", display[i].item_Name);
        printf("Stock:%d\n", display[i].stock);
        printf("Price:%.2f\n", display[i].latest_Price);
        printf("Total Value:%.2f\n", (display[i].stock)*(display[i].latest_Price));
        printf("\n");
    }
}

void addItem(InventoryItemType display)
{

    // NOTE/BUG: because this is passed by _value_ nothing will be retained
    // after function return

    printf("\nEnter details of item \n\n");
    printf("Enter Item Name: \n");
    scanf("%s", display.item_Name);
    printf("\nEnter Item no: \n");
    scanf("%s", display.item_Number);

    printf("\nEnter Stock: \n");
    scanf("%d", &display.stock);

    printf("\nPurchase Price: \n");
    scanf("%f", &display.latest_Price);
}
#else
void displayInventory(InventoryItemType *item,int count)
{
    int i;
    for (i=0; i<count; i++, item++) {
        printf("Name:%s\n", item->item_Name);
        printf("Stock:%d\n", item->stock);
        printf("Price:%.2f\n", item->latest_Price);
        printf("Total Value:%.2f\n", (item->stock)*(item->latest_Price));
        printf("\n");
    }
}

void addItem(InventoryItemType *item)
{

    printf("\nEnter details of item \n\n");

    printf("Enter Item Name: \n");
    scanf("%s", item->item_Name);

    printf("\nEnter Item no: \n");
    scanf("%s", item->item_Number);

    printf("\nEnter Stock: \n");
    scanf("%d", &item->stock);

    printf("\nPurchase Price: \n");
    scanf("%f", &item->latest_Price);
}
#endif

您的代碼存在許多問題。

InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE] ;

這聲明了一個InventoryItemType指針的維度MAX_INVENTORY_SIZE數組。 這些指針未初始化,因此您需要為其分配內存。 你這樣做:

inventoryItems[count]= (InventoryItemType*)malloc(sizeof(InventoryItemType));
  1. 不要施放malloc

  2. count變量初始化為1,永遠不會更改。 因此,每次為inventoryItems[1]分配新內存時,您正在丟失前一個malloc調用的指針,因此它正在泄漏。

打印數據結構時,您執行以下操作:

for(i=0; i<MAX_INVENTORY_SIZE; i++)
    {
        printf("Name:%s\n", display[i].item_Name);
        ...

inventoryItems[i]適用於所有i != 1未初始化,這會產生未定義的行為。

當結構本身具有庫存中下一個項目的指針next指針時,有一個InventoryItemType指針數組的重點是什么。 看來你在這里混合概念,鏈表和數組。 我建議你選一個堅持下去。

為什么你

void addItem(InventoryItemType display);

像這樣聲明addItem display只是原始的副本,因此display值的任何更改都只會影響display ,而不會影響原始display 所以,當你這樣做

addItem(*inventoryItems[count], count);

您將副本傳遞給addItem並且只更改副本, inventoryItems[count]保持不變。 你的函數也只需要一個參數,你傳遞兩個參數。

addItem應該帶一個指針,這樣更改就可以通過指針進入原始狀態。 該函數應如下所示:

int addItem(InventoryItemType *display);
{

    if(display == NULL)
        return 0;

    printf("\nEnter details of item \n\n");
    printf("Enter Item Name: \n");
    if(scanf("%19s", display->item_Name) != 1)
        return 0;

    clear_stdin();

    printf("\nEnter Item no: \n");
    if(scanf("%2s", display->item_Number) != 1)
        return 0;

    clear_stdin();

    printf("\nEnter Stock: \n");
    if(scanf("%d", &display->stock) != 1)
        return 0;

    printf("\nPurchase Price: \n");
    if(scanf("%f", &display->latest_Price) != 1)
        return 0;


    return 1;
}

該函數應在成功時返回1,否則返回0。 addItem的調用者將知道addItem是否失敗。 如果你將函數聲明為void ,那么你永遠不會知道函數是否有效。

clear_stdin看起來像這樣:

 void clear_stdin(void)
 {
     int c;
     while((c = getchar()) != '\n' && c != EOF);
 }

編輯

由於您已經進行了更新,並且您已決定使用該陣列,因此我可以為您提供更多指示。

你宣稱要有很多記憶。 您可以在addItem之前分配內存並將新分配的內存傳遞給addItem ,或者在addItem本身中分配內存並將其返回。 你的addItem已經這樣做,所以第一行

inventoryItems[item_count]=(InventoryItemType*)malloc(sizeof(InventoryItemType));

沒有必要,因為addItem會為你做這addItem

我將addItem更改為如下所示:

InventoryItemType *addItem(void)
{
    InventoryItemType *current = calloc(1, sizeof *current);
    if(current == NULL)
        return NULL;

    printf("\nEnter details of item \n\n");
    printf("Enter Item no: \n");
    scanf("%2s", current->item_Number);

    clear_stdin();

    printf("Enter Item Name: \n");
    scanf("%20s", current->item_Name);

    clear_stdin();

    printf("Enter Stock: \n");
    scanf("%d", &current->stock);
    printf("Enter Purchase Price: \n");
    scanf("%f", &current->latest_Price);
    current->selling_Price=(current->latest_Price)*1.5;
    current->total_Sold=0;
    system("cls");

    return current;
}

因為addItem為新對象分配內存,所以您不需要傳遞數組,也不需要傳遞要存儲它的索引(或鍵)。 然后在main你可以這樣做:

case 'C':
    // checking that you don't step outside of bounds
    if(item_count == MAX_INVENTORY_SIZE - 1)
    {
        fprintf(stderr, "Array is full\n");
        break;
    }

    inventoryItems[item_count] = addItem();
    if(inventoryItems[item_count] == NULL)
    {
        fprintf(stderr, "Not enough memory\n");
        break;
    }

    item_count++;
    continue;

case 'D':
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM