[英]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", ¤t[key].stock);
printf("Enter Purchase Price: \n");
scanf("%f", ¤t[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));
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", ¤t->stock);
printf("Enter Purchase Price: \n");
scanf("%f", ¤t->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.