My pointers and struct code is displaying garbage values - c

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':
...

Related

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;

Menu system in c

I'm having serious trouble with my program it is supposed to provide a menu and do all the functions the code is pretty explanatory my problem is I only have visual studios which doesnt allow scanf and scanf_s and messes with things so I use online compilers but those are still iffy. Can any one help and give me some tips. I'm having trouble with the math and function to list accounts, some whiles are empty as well I wasn't sure if that was best to use. I'm relatively new to this forum. It also can't have struct and can only be in C :-(
#include <stdio.h>
char name[20];
float avail_bal;
void options();
void open();
void list();
void deposit();
void withdraw();
void exit();
int main(void)
{
char option;
while(1){
printf("****Banking System WELCOME****\n");
printf("Enter 1-5 of the following options: \n");
option = getchar();
scanf("%c\n", &option);
switch(option)
{
case '1': open();
break;
case '2': list();
break;
case '3': deposit();
break;
case '4': withdraw();
break;
case '5': return 0;
default: exit();
break;
}
}
return 0;
}
void options()
{
printf("1. Open Account\n");
printf("2. List Accounts\n");
printf("3. Deposit\n");
printf("4. Withdraw\n");
printf("5. Exit");
}
void open()
{
float avail_bal = 0;
char name[20];
int acc_num;
printf("Open new account(enter number 1-5)\n\n");
scanf("%d", &acc_num);
printf("Account number: %d\n");
printf("Available balance: %f\n");
}
void list()
{
}
void deposit()
{
float add;
int acc_num;
printf("Which count do you want to deposit money in?");
scanf(" %d", &acc_num);
printf("Amount to deposit: ");
scanf("%f", &add);
while()
{
}
}
void withdraw()
{
int acc_num;
float withdraw;
printf("Account to withdraw from: ");
scanf("%d", &acc_num);
printf("Amount to withdraw from account: ")
scanf("%f", &withdraw);
while()
{
printf("Current balance for account %d: %f ");
break;
} acc_num++
}
The problem with scanf was interesting. Here is an example for how to do without (although you shouldn't) such that you can play with your code easier.
#include <stdio.h>
#include <stdlib.h>
// only 5 accounts possible
int accounts[5];
// each its balance
float avail_bal[5];
void options();
// open(P) is a standard Posix function
void bopen();
void list();
void deposit();
void withdraw();
// exit(3) is a standard C function
void pexit();
int main(void)
{
char option;
while (1) {
printf("****Banking System WELCOME****\n");
printf("Enter 1-5 of the following options: \n");
options();
option = getc(stdin);
// swallow the '\n'
getc(stdin);
switch (option) {
case '1':
bopen();
break;
case '2':
list();
break;
case '3':
deposit();
break;
case '4':
withdraw();
break;
case '5':
pexit();
default:
pexit();
}
}
return 0;
}
void options()
{
puts("1. Open Account");
puts("2. List Accounts");
puts("3. Deposit");
puts("4. Withdraw");
puts("5. Exit");
}
void bopen()
{
int acc_num;
char c;
puts("Open new account(enter number 1-5)");
c = getc(stdin);
getc(stdin);
// assuming ASCII here where the digits 0-9 start at place 48 in the table
acc_num = (int) c - 48;
if (acc_num < 1 || acc_num > 5) {
puts("Account number must be between one and five inclusive");
return;
}
if (accounts[acc_num] != 0) {
printf("Account number %d is already taken\n", acc_num);
return;
}
// mark account as taken
accounts[acc_num] = 1;
// spend a fiver for the new client for being a new client
avail_bal[acc_num] = 5.0;
printf("Account number: %d\n", acc_num);
printf("Available balance: %f\n", avail_bal[acc_num]);
}
void list()
{
int i;
for (i = 0; i < 5; i++) {
if (accounts[i] != 0) {
printf("Account 000%d: %f\n", i, avail_bal[i]);
}
}
}
void deposit()
{
float add;
int acc_num;
char c;
char s[100];
puts("Which account do you want to deposit money in?");
c = getc(stdin);
getc(stdin);
acc_num = (int) c - 48;
printf("Amount to deposit: ");
// to get a number without scanf() we have to read the input as a string
// (fgets() adds a '\0' at the end, so keep a seat free for it)
fgets(s, 99, stdin);
// and convert it to a double (atof() only for brevity, use strtod() instead)
add = atof(s);
avail_bal[acc_num] += add;
printf("Amount deposited %f\n", add);
}
void withdraw()
{
int acc_num;
float withdraw;
char c;
char s[100];
// all checks ommitted!
puts("Account to withdraw from: ");
c = getc(stdin);
getc(stdin);
acc_num = (int) c - 48;
puts("Amount to withdraw from account: ");
fgets(s, 99, stdin);
withdraw = atof(s);
avail_bal[acc_num] -= withdraw;
printf("Current balance for account %d: %f\n", acc_num, avail_bal[acc_num]);
}
void pexit()
{
// place logic to save data here or use a function triggered by atexit() for that task
puts("Imagine all of your data would have been put in a safe place!");
exit(EXIT_SUCCESS);
}
Just replace the constructs with scanf before you pass your work for grading.
If you're using integer values as options why you are using character's
#include <stdio.h>
char name[20];
float avail_bal;
void options();
void open();
void list();
void deposit();
void withdraw();
void exit();
int main(void)
{
int option;
printf("****Banking System WELCOME****\n");
void options();
printf("Enter 1-5 of the following options: \n");
scanf("%d",&option);
switch(option)
{
case 1: open();
break;
case 2: list();
break;
case 3: deposit();
break;
case 4: withdraw();
break;
case 5: return 0;
default: exit();
break;
}
return 0;
}
void options()
{
printf("1. Open Account\n");
printf("2. List Accounts\n");
printf("3. Deposit\n");
printf("4. Withdraw\n");
printf("5. Exit");
}
void open()
{
float avail_bal = 0;
char name[20];
int acc_num;
printf("Open new account(enter number 1-5)\n\n");
scanf("%d", &acc_num);
printf("Account number: %d\n");
printf("Available balance: %f\n");
}
void list()
{
}
void deposit()
{
float add;
int acc_num;
printf("Which count do you want to deposit money in?");
scanf(" %d", &acc_num);
printf("Amount to deposit: ");
scanf("%f", &add);
while()
{
}
}
void withdraw()
{
int acc_num;
float withdraw;
printf("Account to withdraw from: ");
scanf("%d", &acc_num);
printf("Amount to withdraw from account: ")
scanf("%f", &withdraw);
while()
{
printf("Current balance for account %d: %f ");
break;
} acc_num++
}

Printing the array of structures

The addInfo() adds information into the array of structures and the function printList() outputs all of the elements of that array. But my printList() is outputting only the last element that was added. What can be wrong? Does it add elemets into the array incorrectly?
#include <stdio.h>
#include <stdlib.h>
//structure Location
typedef struct Location{
char locName[35];
char locDesc[85];
float latitude;
float longitude;
} LocationArray;
void addInfo(LocationArray **myArray, int*, int*);
void printList(LocationArray **myArray, int*);
void quitProgram();
void resizeArray(LocationArray **myArray, int*);
//Menu that receives the user input
//and performs corresponding operations based
//on the menu choice
void printMenu(LocationArray **myArray, int *count, int *max){
printf("Hello! Please choose from the menu: \n");
printf("Type 'A' or 'a' for adding additional location to the array\n");
printf("Type 'P' or 'p' for printing the current list of locations\n");
printf("Type 'Q' or 'q' to quit the program\n");
char input = 0;
scanf(" %c", &input);
//Handles the invalid character input
//exits if the character does not correspond
//to the valid menu option
while(input != 'A' && input != 'a'
&& input != 'P' && input != 'p'
&& input != 'Q' && input != 'q'){
printf("Invalid character! Try entering a char again: \n");
scanf(" %c", &input);
}
//Calls other functions
//based on the character input
switch(input){
case 'A':
case 'a':
addInfo(myArray, count, max); //Calls function that adds more locations into the array
break;
case 'P':
case 'p':
printList(myArray, count); //Calls the function that prints the current list of locations
break;
case 'Q':
case 'q':
quitProgram(); //Calls the function that terminates the program
break;
}
}
//Adds info into the array of structures
void addInfo(LocationArray **myArray, int *count, int *numberOfLoc){
if(*count == *numberOfLoc){ // Checks if the array is already full
resizeArray(myArray, numberOfLoc); //Resizes the array if it's full
printf("Please enter the name for the location:\n");
scanf(" %[^\n]", &(*myArray)->locName); //Gets the user input for the Location Name
printf("\nNow enter the description:\n");
scanf(" %[^\n]", &(*myArray)->locDesc); //Gets the user input for the Location Description
printf("\nNow enter the value for the latitude:\n");
scanf("%f", &(*myArray)->latitude); //Gets the user input for the Latitude
printf("\nNow enter the value for the longitude:\n");
scanf("%f", &(*myArray)->longitude); //Gets the user input for the Latitude
(*count)++; //Increment the count
}
else{ //Else, a used fills it out
printf("Please enter the name for the location:\n");
scanf(" %[^\n]", &(*myArray)->locName); //Gets the user input for the Location Name
printf("\nNow enter the description:\n");
scanf(" %[^\n]", &(*myArray)->locDesc); //Gets the user input for the Location Description
printf("\nNow enter the value for the latitude:\n");
scanf("%f", &(*myArray)->latitude); //Gets the user input for the Latitude
printf("\nNow enter the value for the longitude:\n");
scanf("%f", &(*myArray)->longitude); //Gets the user input for the Latitude
(*count)++; //Increment the count
}
}
//Resizes(doubles) the array size if the max limit is achieved
void resizeArray(LocationArray **myArray, int *numberOfLoc){
*numberOfLoc = *numberOfLoc * 2; //Double the size
LocationArray *temp;
temp = (LocationArray*)realloc(*myArray, *numberOfLoc *sizeof(LocationArray)); //Reallocates more memory
//Checks if the memory heap is exhausted
if(temp == NULL){
printf("The memory heap is exhausted!\n");
}
else{
*myArray = temp; //Copy from the temp struct variable to myArray
}
}
//Prints all of the elements of the array
void printList(LocationArray **myArray, int *count){
if((*count) == 0){ //If the list is empty, then return
printf("The list is empty!");
return;
}
int i;
for(i = 0; i < (*count); i++){
printf("Location name: %s\n", (*myArray[i]).locName);
printf("Description: %s\n", (*myArray[i]).locDesc);
printf("Latitude: %f\n", (*myArray[i]).latitude);
printf("Longitude: %f\n", (*myArray[i]).longitude);
}
}
//Quits the program
void quitProgram(){
printf("Bye!");
exit(0);
}
int main()
{
printf("How many locations would you like to be inside the array?\n");
int numberOfLoc = 0; //variable for storing the size of the LocationArray
scanf(" %d", &numberOfLoc); //gets the user input and stores in numerOfLoc
LocationArray *myArray; //declares a LocationArray with the size of numberOfLoc
myArray = (LocationArray*)malloc(numberOfLoc*sizeof(LocationArray));
int count = 0;
while(1){
//Prints the menu
printMenu(&myArray, &count, &numberOfLoc);
}
//Free the pointer
free(myArray);
return 0;
}
In printList, you have the lines
for(i = 0; i < (*count); i++){
printf("Location name: %s\n", (*myArray[i]).locName);
printf("Description: %s\n", (*myArray[i]).locDesc);
printf("Latitude: %f\n", (*myArray[i]).latitude);
printf("Longitude: %f\n", (*myArray[i]).longitude);
}
Use of *myArray[i] is incorrect. That is equivalent to *(myArray[i]). You need to use: (*myArray)[i].
for(i = 0; i < (*count); i++){
printf("Location name: %s\n", (*myArray)[i].locName);
printf("Description: %s\n", (*myArray)[i].locDesc);
printf("Latitude: %f\n", (*myArray)[i].latitude);
printf("Longitude: %f\n", (*myArray)[i].longitude);
}
You can make code in printList simpler by changing the argument to
LocationArray *myArray and int count.
void printList(LocationArray *myArray, int count){
if(count == 0){ //If the list is empty, then return
printf("The list is empty!");
return;
}
int i;
for(i = 0; i < count; i++){
printf("Location name: %s\n", myArray[i].locName);
printf("Description: %s\n", myArray[i].locDesc);
printf("Latitude: %f\n", myArray[i].latitude);
printf("Longitude: %f\n", myArray[i].longitude);
}
}
and make sure to change the call to the function. Instead of
printList(myArray, count);
use
printList(*myArray, *count);
Further cleanup
scanf(" %[^\n]", &(*myArray)->locName);
scanf(" %[^\n]", &(*myArray)->locDesc);
are wrong on two accounts.
You don't need to use &.
You need to use the count-th element of myArray. The above always store the data in the first element of myArray.
use
scanf(" %[^\n]", (*myArray)[*count].locName);
scanf(" %[^\n]", (*myArray)[*count].locDesc);
Modify the other scanf lines also to:
scanf("%f", &(*myArray)[*count].latitude);
scanf("%f", &(*myArray)[*count].longitude);

C: Stack implementation

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--];

Why does it keep crashing?

Any idea on when I choose to add a client and as soon as I enter in a client ID the program crashes for that entry?
#include <stdio.h>
#include <stdlib.h>
struct client
{
int clID;
char cname;
char caddress;
char cemail;
int cfees;
int ceID;
char cename;
}typedef client;
struct employee
{
int empID;
char ename;
double erate;
double ehours;
double esalary;
int ecID;
}typedef employee;
void mainMenu();
void clientMenu();
void empMenu();
void getClient(client* pcli);
void getEmp(employee* pemp);
void payroll(employee* pemp);
void dispPay(employee* pemp);
void dispClient(client* pcli);
void dispEmployee(employee* pemp);
int main()
{
client cli[100];
client* pcli = &cli[0];
employee emp[20];
employee* pemp = &emp[0];
int answer = -1;
int mchoice;
int cchoice;
int echoice;
int ccount;
int ecount;
int input[9];
int* psearchclientID;
int i;
printf("Do you wish to start the program? 1 for yes 2 for no: ");
scanf("%d", &answer);
if(answer ==1)
{
while(mchoice != 3)
{
mainMenu();
scanf("%d", &mchoice);
switch(mchoice)
{
case 1: while(cchoice != 3)
{
clientMenu();
scanf("%d", &cchoice);
switch(cchoice)
{
case 1: getClient(pcli + i);
ccount++;
break;
case 2: printf("Enter the client ID to search for: ");
psearchclientID = fgets(input, 9, stdin);
strtok(input, "\n");
for(i = 0; i < 1; i++)
{
if(strcmpi(psearchclientID, (pcli->clID + i)) == 0)
printf("Client found at position %d\n", i);
else
printf("Client not found!");
}//end for
break;
}//end client switch
}//end client while
cchoice = 0;
break;
case 2: while(echoice != 4)
{
empMenu();
scanf("%d", &echoice);
switch(echoice)
{
case 1: getEmp(pemp + i);
ecount++;
break;
case 2: payroll(pemp + i);
dispPay(pemp + i);
break;
case 3:
break;
}//end emp switch
}//end emp while
echoice =0;
break;
}//end switch
}//end main while
}//end if
else if(answer ==2)
{
printf("Goodbye!");
exit(0);
}
return 0;
}//end main
void mainMenu()
{
printf("1-Client Menu\n"
"2-Employee Menu\n"
"3-Quit\n");
printf("Enter a choice from the menu: ");
}//end mainMenu
void clientMenu()
{
printf("1-Add a client\n"
"2-Search client\n"
"3-Go Back to Main Menu\n");
printf("Enter a choice from the menu: ");
}//end clientMenu
void empMenu()
{
printf("1-Add an Employee\n"
"2-Process an Employee(payroll)\n"
"3-Search Employee\n"
"4-Go Back to Main Menu\n");
printf("Enter a choice from the menu: ");
}//end empMenu
This is specifically the code for entering in the client info
void getClient(client* pcli)
{
printf("Enter client ID: ");
scanf("%d", &pcli->clID);
printf("Enter client name: ");
scanf("%s", &pcli->cname);
printf("Enter client address: ");
scanf("%s", &pcli->caddress);
printf("Enter client email: ");
scanf("%s", &pcli->cemail);
printf("Enter monthly service fees:" );
scanf("%d", &pcli->cfees);
}//end getClient
void getEmp(employee* pemp)
{
printf("Enter employee ID: ");
scanf("%d", &pemp->empID);
printf("Enter employee name: ");
scanf("%s", &pemp->ename);
printf("Enter employee hourly rate: ");
scanf("%lf", &pemp->erate);
printf("Enter employee hours worked: ");
scanf("%lf", &pemp->ehours);
}//end getEmp
void payroll(employee* pemp)
{
pemp->esalary = pemp->erate * pemp->ehours;
}//end payroll
void dispPay(employee* pemp)
{
printf("Employee ID %d\nEmployee Salary: %2.2f\n", pemp->empID, pemp->esalary);
}//end dispPay
This is where the information would be displayed
void dispClient(client* pcli)
{
printf("Client ID: %d\n Name: %s\n Address: %s\n Email: %s\n Monthly fees: %d\n Employee assigned: %d\n Employee name: %s\n", pcli->clID, pcli->cname, pcli->caddress, pcli->cemail, pcli->cfees, pcli->ceID, pcli->cename);
}//end dispClient
void dispEmployee(employee* pemp)
{
printf("Employee ID: %d\n Name: %s\n Hourly Rate: %2.2f\n Hours worked: %2.2f\n Salary: %2.2f\n Client(s) assigned: %s\n", pemp->empID, pemp->ename, pemp->erate, pemp->ehours, pemp->esalary, pemp->ecID);
}//end dispEmp
You don't include & (address) operator for %s (strings) while reading. For example, in function getClient, use
printf("Enter employee name: ");
scanf("%s", pemp->ename);
This is one of the problems in your program.
Your clientMenu switch statement to add a client calls:
case 1: getClient(pcli + i);
It is possible to be in that routine where i is uninitialized, so it could be anything, and very likely beyond the bounds of your 100 element array. In that case getClient will very likely be operating in memory it does not own, making your program liable to crash.
It's possible there's more than that issue at play, as well. As others have stated, more information about the crash would help.

Resources