C: Stack implementation - c

following code for stack implementation, produces runtime-errors, although it does compile .. Can anyone help me identify find the error?
#include<stdio.h>
#define size 5
// declared a structure for stack which has an int array and top as it's members..
struct stack{
int a[size],top;
}s;
// following method pushes element 'item' in stack when called after checking if stack-overflows or not?
void push(int item){
if(s.top >= size-1)
printf("\nStack overflow..\n");
else
s.a[++s.top] = item;
}
following method pops one element when called..
int pop(){
if(s.top == -1){
printf("\n..Stack underflow..\n");
return 0;
}
return s.a[s.top];
}
// displays elements in the stack till a[top]
void display(){
int i;
for(i = s.top; i>=0; i--){
printf("\n%d", &s.a[i]);
}
}
// main() method..
int main(){
s.top = -1;
int item, choice;
char ans;
printf(" ..Stack Implementation..\n");
printf("-----------------------------");
do{
printf("\nMain Menu");
printf("\n-------------");
printf("\n 1. Push\n 2. Pop\n 3. Display\n 4. Exit\n");
printf("\n Enter your choice: ");
scanf("%d", choice);
switch(choice){
case 1:
printf("\nEnter item to be pushed: ");
scanf("%d", &item);
push(item);
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
return 0;
}
printf("\n Want to continue? :");
scanf("%c", &ans);
}while(ans == 'Y' || ans == 'y');
return 0;
}

There is a small typo [I think so, as your other occurrences are correct]. Change
scanf("%d", choice);
to
scanf("%d", &choice);
Also, there is a small problem in scanf("%c", &ans);. It will suffer from the previously-pressed enter. Use
scanf(" %c", &ans); //mind the space before %
Other Issues: [Added after the edit]
printf("\n%d", &s.a[i]); -- get rid of the &, don't need that in printf()
return s.a[s.top]; should be return s.a[s.top--];

Related

Values are getting stored in different stack even though different variables are used in the code for each stack

I wanted to create 4 stacks, 1 for each subject. Then in each stack store number of days left for each assignment to be submitted. This is the code I have written. The code works with the exception of 1 flaw:
When values are stored in one stack they also show up in the other stacks with value 0 and same number of elements for example :
I store values 5,20,7 in the stack of ds exit that stack and go to the stack of dsgt and store 9,11 and then on printing the values in stack of dsgt the code prints out as " 0 0 0 9 11" here 0 0 0 are the 3 elements of the 1st stack. Now on exiting the stack of dsgt and going back to stack of ds and printing its value the output is "5 7 20 0 0 " , 0 0 here are the elements of the stack of dsgt which I dont want to print with ds and rest of the stacks.
#include <stdio.h>
#include <conio.h>
#define MAXSIZE 20
int st1[MAXSIZE];
int st2[MAXSIZE];
int st3[MAXSIZE];
int st4[MAXSIZE];
int top = -1;
void push(int st[], int item);
int pop(int st[]);
int peek(int st[]);
void display(int st[]);
void sort(int st[]);
int main() {
int subj;
printf("\nEnter the number associated with the Subject assignment that has to be tracked\n");
int choice = 0, item1;
do {
printf("\n 1. Data Structures");
printf("\n 2. DSGT ");
printf("\n 3. CG ");
printf("\n 4. Math");
printf("\n 5. Exit Code");
printf("\n Enter Your Choice");
scanf("%d", & choice);
switch (choice) {
case 1:
ds();
break;
case 2:
dsgt();
break;
case 3:
cg();
break;
case 4:
math();
break;
case 5:
printf("Exited");
break;
default:
printf("\n Wrong Input");
}
} while (choice != 5);
return 0;
}
int dsgt() {
int choice, item2;
do {
printf("Stack Operation \n");
printf("\n 1. Add A New Assignment");
printf("\n 2. Remove the latest Completed Assignment ");
printf("\n 3. View the latest Pending Assignment ");
printf("\n 4. View All the pending Assignments");
printf("\n 5. Exit Code");
printf("\n Enter Your Choice");
scanf("%d", & choice);
switch (choice) {
case 1:
printf("\n Enter the Number of Days Left for the Assignment to be Submitted");
scanf("\n %d", & item2);
push(st2, item2);
sort(st2);
break;
case 2:
item2 = pop(st2);
printf("\n Removed Assignment is: \n %d", item2);
break;
case 3:
item2 = peek(st2);
printf("\n The Latest Assignment to be Submitted is:%d", item2);
break;
case 4:
display(st2);
break;
case 5:
printf("Exited");
break;
default:
printf("\n Wrong Input");
}
} while (choice != 5);
}
int ds() {
int choice, item1;
do {
printf("Stack Operation \n");
printf("\n 1. Add A New Assignment");
printf("\n 2. Remove the latest Completed Assignment ");
printf("\n 3. View the latest Pending Assignment ");
printf("\n 4. View All the pending Assignments");
printf("\n 5. Exit Code");
printf("\n Enter Your Choice");
scanf("%d", & choice);
switch (choice) {
case 1:
printf("\n Enter the Number of Days Left for the Assignment to be Submitted");
scanf("\n %d", & item1);
push(st1, item1);
sort(st1);
break;
case 2:
item1 = pop(st1);
printf("\n Removed Assignment is: \n %d", item1);
break;
case 3:
item1 = peek(st1);
printf("\n The Latest Assignment to be Submitted is:%d", item1);
break;
case 4:
display(st1);
break;
case 5:
printf("Exited");
break;
default:
printf("\n Wrong Input");
}
} while (choice != 5);
}
int cg() {
int choice, item3;
do {
printf("Stack Operation \n");
printf("\n 1. Add A New Assignment");
printf("\n 2. Remove the latest Completed Assignment ");
printf("\n 3. View the latest Pending Assignment ");
printf("\n 4. View All the pending Assignments");
printf("\n 5. Exit Code");
printf("\n Enter Your Choice");
scanf("%d", & choice);
switch (choice) {
case 1:
printf("\n Enter the Number of Days Left for the Assignment to be Submitted");
scanf("\n %d", & item3);
push(st3, item3);
sort(st3);
break;
case 2:
item3 = pop(st3);
printf("\n Removed Assignment is: \n %d", item3);
break;
case 3:
item3 = peek(st3);
printf("\n The Latest Assignment to be Submitted is:%d", item3);
break;
case 4:
display(st3);
break;
case 5:
printf("Exited");
break;
default:
printf("\n Wrong Input");
}
} while (choice != 5);
}
int math() {
int choice, item4;
do {
printf("Stack Operation \n");
printf("\n 1. Add A New Assignment");
printf("\n 2. Remove the latest Completed Assignment ");
printf("\n 3. View the latest Pending Assignment ");
printf("\n 4. View All the pending Assignments");
printf("\n 5. Exit Code");
printf("\n Enter Your Choice");
scanf("%d", & choice);
switch (choice) {
case 1:
printf("\n Enter the Number of Days Left for the Assignment to be Submitted");
scanf("\n %d", & item4);
push(st4, item4);
sort(st4);
break;
case 2:
item4 = pop(st4);
printf("\n Removed Assignment is: \n %d", item4);
break;
case 3:
item4 = peek(st4);
printf("\n The Latest Assignment to be Submitted is:%d", item4);
break;
case 4:
display(st4);
break;
case 5:
printf("Exited");
break;
default:
printf("\n Wrong Input");
}
} while (choice != 5);
}
void push(int st[], int item) {
if (top == MAXSIZE - 1) {
printf("\n You Have a lot of Assignments Due, GET WORKING!!!");
} else {
top = top + 1;
st[top] = item;
}
}
int pop(int st[]) {
int item;
if (top == -1) {
printf("Great Work No Assignment Are Pending");
return 0;
} else {
item = st[top];
top = top - 1;
}
return item;
}
int peek(int st[]) {
int item;
if (top == -1) {
printf("Great Work No Assignment Are Pending");
return 0;
} else {
item = st[top];
return item;
}
}
void display(int st[]) {
if (top == -1) {
printf("Great Work No Assignment Are Pending");
} else {
for (int i = top; i >= 0; i--) {
printf("\n%d\n", st[i]);
}
}
}
void sort(int st[]) {
int tmp, i, j;
for (int i = top; i >= 0; i--) {
for (j = i + 1; j <= top; j++) {
if (st[i] < st[j]) {
tmp = st[j];
st[j] = st[i];
st[i] = tmp;
}
}
}
}
I would recommend that you use a structure for your stacks that contains the array and the top value e.g.
typedef struct{
int stack[MAXSIZE];
int top;
}stack_t;
Then you can declare your stacks and initialize them:
stack_t st1 = {{0}, -1};
stack_t st2 = {{0}, -1};
stack_t st3 = {{0}, -1};
stack_t st4 = {{0}, -1};
or place them in an array
stack_t stacks[4]={
{{0}, -1},
{{0}, -1},
{{0}, -1},
{{0}, -1}, };
You need to declare your functions as follows and update their implementation accordingly:
void push(stack_t* st, int item);
int pop(stack_t* st);
int peek(stack_t st);
void display(stack_t st);
void sort(stack_t* st);
void dsgt(void);
void cg(void);
void math(void);
void ds(void);
The push, pop, sort functions then all use pointers to stack_t e.g.
int pop(stack_t* st) {
int item =0;
if (st->top == -1) {
printf("Great Work No Assignment Are Pending");
} else {
item = st->stack[st->top];
st->top = st->top - 1;
}
return item;
}
display and peek function are okay with stack_t parameter as they don't change it.
If you place all of your stack structures in an array, you then can use a global variable as an index into your stack_t array and reduce the duplication of your choice code.

I cant seem to understand how to restrict my scanf to only numbers of float

#include <stdio.h>
#include <string.h>
#define mL 5
#define NL 20
#define UL 6
struct LIST
{
char n[NL];
float am;
char u[UL];
};
struct array
{
struct LIST array;
};
void addCityInformation(struct array *add, int *items);
void printCities(struct array *all, int items);
int main(void)
{
struct array shopping[mL];
int choice, nrOfItemsAdded = 0;
do
{
printf("\nWhat du you want to do?");
printf("\n1 - add grocery");
printf("\n2 - print shopping list");
printf("\n3 - exit");
printf("\nYour choice: ");
scanf("%d", &choice);
while(getchar() != '\n');
switch (choice)
{
case 1:
addCityInformation(&shopping[nrOfItemsAdded], &nrOfItemsAdded);
break;
case 2:
printCities(shopping, nrOfItemsAdded);
break;
case 3:
printf("Exiting program\n\n");
break;
default:
printf("Invalid input\n\n");
break;
}
}
while(choice != 3);
return 0;
}
int clean_stdin()
{
while (getchar()!='\n');
}
void addCityInformation(struct array *add, int *items)
{
if(*items == mL)
printf("No more space in the list\n");
else
{
printf("Enter name: ");
fgets(add->array.n, NL, stdin);
add->array.n[strlen(add->array.n)-1] = '\0';
do {
printf("Enter amount: ");
}while (scanf("%f", &add->array.am )); //loop untill other than float
getchar();
printf("Enter unit: ");
fgets((add->array.u), UL, stdin);
add->array.u[strlen(add->array.u)-1] = '\0';
(*items)++;
}
}
void printCities(struct array *all, int items)
{
printf("\n\n%-20s %-15s %-9s | %-6s\n", "Name", "amount", "unit");
printf("--------------------------------------------------------\n");
for(int i = 0; i < items; i++)
printf("%-20s %-15.1f %-9.4s \n", all[i].array.n, all[i].array.am, all[i].array.u);
}
This is my loop beside that i am only showing a part of the code. It now just continues to give enter amount and letting me register it in the struct. I want to restrict the user to only entering positive numbers and no character at all. And if he types a character it should rerun the loop even if it is 123Av123 it should run the loop and only register the correct number
Edit: now showing the whole code//loop untill other than float is what i want help with
int check=scanf("%f", &add->array.am )
if(check!=1||add->array.am<0){
printf("Incorrect input");
return 1;
}
I think that will do it.
Edit: you wanted it to rerun after so use continue; instead of return;

Can someone tell how make user input the element in array and to insert element at the last position?

/*ARRAY INSERTION AT THE END*/
#include<stdio.h>
#include<conio.h>
int main()
{
int i,n,insrt;
char option;
int array[100];
printf("\nWHAT IS THE TOTAL NUMBER OF ARRAY YO WANT ?\n");
scanf(" %d", &n);
for(i=0;i<n;i++)
{
printf("\nENTER THE NO FOR YOUR ARRAY:\t");
scanf(" %d", &array[i]);
}
printf("\nYOU HAVE FOLLOWING NO IN THE LIST:\n");
for(i=0;i<n;i++)
{
printf(" %d==>", array[i]);
}printf("NULL");
do
{
printf("\nENTER THE VALUE TO BE INSERTED AT THE END:\t");
scanf(" %d", &insrt);
for(i=0 ;i<n;i++)
{
if (array[i] == 0)
{
array[i] = insrt;
printf("\nINSERTION SUCCESSFULL!!\n");
break;
}
else
{
printf("\nTHE ARRAY IS FULL.\n");
break;
}
}
printf("\nDO YOU WANT TO CONTINUE ? TYPE (Y FOR YES AND N FOR NO):\t");
scanf(" %c", &option);
}while(option == 'Y' || option == 'y');
printf("\nYOU HAVE FOLLOWING NO IN THE LIST:\n");
for(i=0;i<n;i++)
{
printf(" %d==>", array[i]);
}
printf("NULL");
getch();
}
Insertion at the end of the array is not working, tried everything I know but it is still not working and instead of insertion it only prints that array is full.
I know that there is a fault in loop statement but I am unable to fix it.
https://i.stack.imgur.com/xO6Jz.png
1st mistake:
You are taking input n after defining the array. It should be:
scanf(" %d", &n);
int array[n];
2nd mistake:
else
{
printf("\nTHE ARRAY IS FULL.\n");
break;
}
for i=0, a[i] = 432 this is not equal to zero, so it will go to else, and print "The Array is Full".
Just keep track of the number of elements inserted in array, if no_elem == n-1, then print "Array is full" and break;.

My pointers and struct code is displaying garbage values

Currently, I am trying to create a program that takes inventory of a stores products. I have been able to create a function that allows the user to input new items in a struct array but when I attempt to print the values I get garbage values. (Please ignore the switch statements as the code is work in progress).
#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);
}
Update
I attempted to apply all answers (with a series of trial and error) and came up with this code. I currently have the code properly taking in a new item and displaying that item, but it breaks down after adding more items(if I continue through the errors I get garbage display values). I am pretty certain it has to do with the way in which I am allocating memory via malloc. My goal is to use malloc to create the space for the item before initializing values.
Edited code:
#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;
}
There are a number of bugs/conflicts. Too many to comment on individually. I've annotated and corrected the code, showing bugs and before/after. There is still more work to do, but this should get you closer.
#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
There are many problems with your code.
InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE] ;
This declares an array of dimension MAX_INVENTORY_SIZE of InventoryItemType
pointers. These pointers are uninitialized, so you need to allocate memory for
it. You do it here:
inventoryItems[count]= (InventoryItemType*)malloc(sizeof(InventoryItemType));
Don't cast malloc
The count variable is initialized to 1 and it is never changed. So every
time you are allocating new memory for inventoryItems[1] and you are losing
the pointer of the previous malloc call, thus it's leaking.
When you print your data structure, you do:
for(i=0; i<MAX_INVENTORY_SIZE; i++)
{
printf("Name:%s\n", display[i].item_Name);
...
but inventoryItems[i] is for all i != 1 uninitialized, this yield undefined
behaviour.
What's the point of having an array of InventoryItemType pointers when the
structure itself has a pointer next pointer for the next item in the inventory. It seems you
are mixing concepts here, linked lists vs arrays. I'd suggest you pick one and
stick to it.
Why did you
void addItem(InventoryItemType display);
declare addItem like this? display is only a copy of the orginal, so any
change of the values of display will only affect display, not the original.
So when you do
addItem(*inventoryItems[count], count);
you are passing a copy to addItem and you only change the copy,
inventoryItems[count] remains unchanged. Also your function takes only one
parameter, you are passing it two.
addItem should take a pointer, so that the changes are done through the
pointer into the original. The function should look like this:
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;
}
The function should return 1 on success, 0 otherwise. The caller of addItem
will know whether addItem failed or not. If you declare the function as
void, then you will never know if the function failes or not.
And clear_stdin could look like this:
void clear_stdin(void)
{
int c;
while((c = getchar()) != '\n' && c != EOF);
}
edit
As you've made an update and you've decided to use the array, then I can give
you a few more pointers.
You are declaring to much memory. Either you allocate memory before addItem
and pass the newly allocated memory to addItem, or you allocate the memory in
addItem itself and return it. Your addItem already does that, so the first
line
inventoryItems[item_count]=(InventoryItemType*)malloc(sizeof(InventoryItemType));
is not necessary, because addItem does that for you.
I'd change addItem to look like this:
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;
}
Because addItem allocates the memory for the new object, you don't need to
pass the array nor the index (or key) where you want to store it. Then in the
main you can do this:
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':
...

Prevent array from accepting duplicate values

I have a stack where I want to push distinct elements. I wrote the following code. But it always checks only first element. If I enter a duplicate value first value, it doesn't accept that, but if I enter a duplicate value of 2nd or 3rd value it accepts it.
For example if I enter 20 and again enter 20 it will not accept the second,
but if I enter 20, 22, 22 it accepts the duplicate. How can I prevent this?
#include <stdio.h>
#define MAXSIZE 5
struct stack
{
int stk[MAXSIZE];
int top;
};
typedef struct stack STACK;
STACK s;
void push(void);
int pop(void);
void display(void);
void main ()
{
int choice;
int option = 1;
s.top = -1;
printf ("STACK OPERATION\n");
while (option)
{
printf ("------------------------------------------\n");
printf (" 1 --> Bus Status \n");
printf (" 2 --> Enter Bus \n");
printf (" 3 --> Exit Bus \n");
printf (" 4 --> EXIT \n");
printf ("------------------------------------------\n");
printf ("Enter your choice\n");
scanf ("%d", &choice);
switch (choice)
{
case 1:
display();
break;
case 2:
push();
break;
case 3:
pop();
break;
case 4:
return;
}
fflush (stdin);
printf ("Do you want to continue(Type 0 or 1)?\n");
scanf ("%d", &option);
}
}
/* Function to add an element to the stack */
void push ()
{
int num,i,j,status=0;
if (s.top == (MAXSIZE - 1))
{
printf ("Terminal is Full\n");
return;
}
else
{
printf ("Enter the Bus Number\n");
scanf ("%d", &num);
if(num<1 || num>30) {
printf("This bus Does not Exist.\n");
}
for(i=0;i<5;i++){
if(s.stk[i]==num){
printf("Bus Already in the Terminal\n");
break;
}
else {
s.top = s.top + 1;
s.stk[s.top] = num;
status=1;
break;
}
}
if(status==1)
printf("Bus %d Successfully Entered\n", num);
}
return;
}
You're bus insert loop is looping through and adds a bus the first time it finds s.stk[i] != num. You need to check to see if the bus is in the station ie search the whole stack before inserting a new bus.
for(i=0;i<5;i++) {
if(s.stk[i]==num){
printf("Bus Already in the Terminal\n");
break;
}
else {
s.top = s.top + 1;
s.stk[s.top] = num;
status=1;
break;
}
}

Resources