Optimizing Code & Opinions - c

#include <stdio.h>
#include <string.h>
typedef struct//Declares structure to hold seven created datatypes.
{
int client_id;
char client_business_name [30];
char client_first_name [20];
char client_last_name [20];
char client_address [40];
float client_budget;
char client_business_info [300];
}Client;
main()
{
Client c[100];
void main_menu (Client[]);
main_menu (c);
system ("PAUSE");
}
void main_menu (Client c[])//Determines what the user wants to do and grants access to one of the 6 functions.
{
int choice;
do{
printf ("1.Add Client\n2.Delete Client\n3.Search Clients\n4.Change Client Information\n5.View Clients\n6.Terminate Program\nChoose an option from above:");
scanf ("%d",&choice);
}while (choice<1||choice>6);
if (choice==1)
{
system ("cls");
void accept (Client []);
accept (c);
}
if (choice==2)
{
system ("cls");
void realocate (Client []);
realocate (c);
}
if (choice==3)
{
system ("cls");
void search (Client []);
search (c);
}
if (choice==4)
{
system ("cls");
void change (Client []);
change (c);
}
if (choice==5)
{
system ("cls");
void view_sort (Client []);
view_sort (c);
}
if (choice==6)
{
system ("cls");
void end (Client []);
end (c);
}
}
void accept (Client c[])//Accepts data from the user.
{
int num,y=0;
printf("How Many Clients Do You Want To Add:");
scanf ("%d",&num);
system ("cls");
while (y<num)
{
printf ("\nEnter Client ID:");
scanf ("%d",&c[y].client_id);
printf ("Enter Buisness Name:");
scanf (" %[^\n]",c[y].client_business_name);
printf ("Enter Client First Name:");
scanf (" %[^\n]",c[y].client_first_name);
printf ("Enter Client Last Name:");
scanf (" %[^\n]",c[y].client_last_name);
printf ("Enter Buisness Address:");
scanf (" %[^\n]",c[y].client_address);
printf ("Enter Client Budget:");
scanf ("%f",&c[y].client_budget);
printf ("Enter Buisness Information:");
scanf (" %[^\n]",c[y].client_business_info);
y++;
}
void recall (Client []);
recall (c);
}
void realocate (Client c[])//Realocates memory of variable the user choses to delete.
{
int key,max=100;
printf ("\nEnter Client ID To Be Deleted:");
scanf ("%d",&key);
system ("cls");
int first = 0;
int last = max - 1;
int middle = (first+last)/2;
while( first <= last )
{
if (c[middle].client_id < key)
first = middle + 1;
else if (c[middle].client_id == key)
{
c[middle].client_id=c[middle+1].client_id;
strcpy(c[middle].client_business_name,c[middle+1].client_business_name);
strcpy(c[middle].client_first_name,c[middle+1].client_first_name);
strcpy(c[middle].client_last_name,c[middle+1].client_last_name);
strcpy(c[middle].client_address,c[middle+1].client_address);
c[middle].client_budget=c[middle+1].client_budget;
strcpy(c[middle].client_business_info,c[middle+1].client_business_info);
printf ("\nClient Removed!");
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
{
printf ("\nClient Not Registered\n");
}
void recall (Client []);
recall (c);
}
void search (Client c[])//Searches for data via a Binary or Linear search.
{
int choice,max=100,ch,cho;
do{
printf ("\n1.Client ID\n2.Client Buisness Name\n3.Client First Name\n4.Client Last Name\nChoose an option to search by:");
scanf ("%d",&choice);
}while (choice<1||choice>4);
if (choice==1)//Binary Search
{
system ("cls");
int search_id1;
printf("Enter Client ID:");
scanf("%d",&search_id1);
system ("cls");
int first = 0;
int last = max - 1;
int middle = (first+last)/2;
while( first <= last )
{
if (c[middle].client_id < search_id1)
first = middle + 1;
else if (c[middle].client_id == search_id1)
{
printf ("Client ID:%d",c[middle].client_id);
printf ("\nBuisness Name:%s",c[middle].client_business_name);
printf ("\nClient First Name:%s",c[middle].client_first_name);
printf ("\nClient Last Name:%s",c[middle].client_last_name);
printf ("\nBuisness Address:%s",c[middle].client_address);
printf ("\nClient Budget:%d",c[middle].client_budget);
printf ("\nBuisness Information:%s",c[middle].client_business_info);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
{
printf("Not found!\n%d is not registered to a existing client.\n",search_id1);
}
}
else if (choice==2)//Binary Search
{
system ("cls");
char search_id2 [30];
printf("Enter Buisness Name:");
scanf(" %[^\n]",search_id2);
system ("cls");
int first = 0;
int last = max - 1;
int middle = (first+last)/2;
while( first <= last )
{
if (strcmp(c[middle].client_business_name,search_id2)<0)
first = middle + 1;
else if (strcmp(c[middle].client_business_name,search_id2)==0)
{
printf ("Client ID:%d",c[middle].client_id);
printf ("\nBuisness Name:%s",c[middle].client_business_name);
printf ("\nClient First Name:%s",c[middle].client_first_name);
printf ("\nClient Last Name:%s",c[middle].client_last_name);
printf ("\nBuisness Address:%s",c[middle].client_address);
printf ("\nClient Budget:%d",c[middle].client_budget);
printf ("\nBuisness Information:%s",c[middle].client_business_info);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
{
printf("Not found!\n%s is not a client.\n",search_id2);
}
}
else if (choice==3)//Linear Search
{
system ("cls");
char search_id3 [20];
printf("Enter Client's First Name:");
scanf(" %[^\n]",search_id3);
system ("cls");
int x=0;
while ((strcmp(c[x].client_first_name,search_id3)!=0) && x<100)
{
if (strcmp(c[x].client_first_name,search_id3)==0)
{
printf ("Client ID:%d",c[x].client_id);
printf ("\nBuisness Name:%s",c[x].client_business_name);
printf ("\nClient First Name:%s",c[x].client_first_name);
printf ("\nClient Last Name:%s",c[x].client_last_name);
printf ("\nBuisness Address:%s",c[x].client_address);
printf ("\nClient Budget:%d",c[x].client_budget);
printf ("\nBuisness Information:%s",c[x].client_business_info);
}
else if (strcmp(c[x].client_first_name,search_id3)!=0)
{
printf("Not found!\n%s is not a client.\n",search_id3);
}
x++;
}
}
else if (choice==4)//Linear Search
{
system ("cls");
char search_id4 [20];
printf("Enter Client's Last Name:");
scanf(" %[^\n]",search_id4);
system ("cls");
int y=0;
while ((strcmp(c[y].client_first_name,search_id4)!=0) && y<100)
{
if (strcmp(c[y].client_first_name,search_id4)==0)
{
printf ("Client ID:%d",c[y].client_id);
printf ("\nBuisness Name:%s",c[y].client_business_name);
printf ("\nClient First Name:%s",c[y].client_first_name);
printf ("\nClient Last Name:%s",c[y].client_last_name);
printf ("\nBuisness Address:%s",c[y].client_address);
printf ("\nClient Budget:%d",c[y].client_budget);
printf ("\nBuisness Information:%s",c[y].client_business_info);
}
else if (strcmp(c[y].client_first_name,search_id4)!=0)
{
printf("Not found!\n%s is not a client.\n",search_id4);
}
y++;
}
}
void recall (Client []);
recall (c);
}
void recall (Client c[])
{
int choice;
do{
printf ("\n\nDo You Want To:\n1.Go Back To The Main Menu\n2.Exit\n");
scanf ("%d",&choice);
}while (choice<1 || choice>2);
if (choice==1)
{
void main_menu (Client []);
main_menu (c);
}
else if (choice==2)
{
void end (Client []);
end (c);
}
}
void end (Client c[])
{
printf ("Thank You!\n");
system ("pause");
system ("cls");
}
I know this seems like a lot of code, but I am new to programming, so I wanted people's opinion on this code in C.
The main function of the program is to deal with clients.
The user can Add, Delete or change clients, or view and search for specific clients.
My main focus is to ensure that I can remove a client, as done in the reallocate function. My other main issue is the Search and sort functions. I would like to find out your opinions on the code, and what I could do to make it better.

Put the function prototypes on top
Use define MAX_CLIENTS 100 instead of typing in 100
Declare a new variable Client_Count you need this to know how many clients you have. Here I declare it as global variable. You could also declare it in main, and then carry it around like you are doing with Client
Use a function for print_client so you don't have to repeat the same code.
You might have to initialize all the clients, go from zero to MAX_CLIENTS, just set client_id to zero, so you know it's not valid or it has been deleted.
-
void main_menu(Client[]);
void accept(Client[]);
void realocate(Client[]);
void search(Client[]);
void view_sort(Client[]);
void change(Client[]);
void end(Client[]);
void recall(Client[]);
#define MAX_CLIENTS 100
int Client_Count;
int main()
{
Client_Count = 0;
Client c[MAX_CLIENTS];
main_menu(c);
system("pause");
return 0;
}
void main_menu(Client c[])//Determines what the user wants to do and grants access to one of the 6 functions.
{
int choice;
do{
printf("1.Add Client\n2.Delete Client\n3.Search Clients\n4.Change Client Information\n5.View Clients\n6.Terminate Program\nChoose an option from above:");
scanf("%d", &choice);
} while (choice < 1 || choice > 6);
system("cls");
if (choice == 1) accept(c);
if (choice == 2) realocate(c);
if (choice == 3) search(c);
if (choice == 4) change(c);
//if (choice == 5) view_sort(c);
if (choice == 6) end(c);
}
void accept(Client c[])//Accepts data from the user.
{
if (Client_Count < MAX_CLIENTS)
{
printf("\nEnter Client ID:");
scanf("%d", &c[Client_Count].client_id);
printf("Enter Buisness Name:");
scanf(" %[^\n]", c[Client_Count].client_business_name);
printf("Enter Client First Name:");
scanf(" %[^\n]", c[Client_Count].client_first_name);
printf("Enter Client Last Name:");
scanf(" %[^\n]", c[Client_Count].client_last_name);
printf("Enter Buisness Address:");
scanf(" %[^\n]", c[Client_Count].client_address);
printf("Enter Client Budget:");
scanf("%f", &c[Client_Count].client_budget);
printf("Enter Buisness Information:");
scanf(" %[^\n]", c[Client_Count].client_business_info);
Client_Count++;
}
else
{
printf("too many\n");
}
recall(c);
}
void print_client(Client *c)
{
printf("Client ID:%d", c->client_id);
printf("\nBuisness Name:%s", c->client_business_name);
printf("\nClient First Name:%s", c->client_first_name);
printf("\nClient Last Name:%s", c->client_last_name);
printf("\nBuisness Address:%s", c->client_address);
printf("\nClient Budget:%d", c->client_budget);
printf("\nBuisness Information:%s", c->client_business_info);
}
void search(Client c[])//Searches for data via a Binary or Linear search.
{
int choice = 0;//initialize
do{
printf("\n1.Client ID\n2.Client Buisness Name\n3.Client First Name\n4.Client Last Name\nChoose an option to search by:");
scanf("%d", &choice);
} while (choice < 1 || choice > 4);
system("cls");
if (choice == 1)//Binary Search
{
int search_id1;
printf("Enter Client ID:");
scanf("%d", &search_id1);
system("cls");
for (int i = 0; i < Client_Count; i++)
{
if (c[i].client_id == search_id1)
{
print_client(&c[i]);
return;
}
}
printf("Not found!\n%d is not registered to a existing client.\n", search_id1);
}
else if (choice == 2)//Binary Search
{
system("cls");
char search_id2[30];
printf("Enter Buisness Name:");
scanf(" %[^\n]", search_id2);
for (int i = 0; i < Client_Count; i++)
{
if (strcmp(c[i].client_business_name, search_id2) == 0)
{
print_client(&c[i]);
return;
}
}
printf("Not found!\n%s is not a client.\n", search_id2);
}
//...
recall(c);
}

Related

New to C, need assistance with function related to structures

I need to make the second function (search_pb) print all matching names entered in the personal_info struct. Right now if there are two duplicate first names it only prints the first one. For example, if I added
First name: "Albert"
Last name: "Einstein"
Phone number:35245
and also added
First name: "Albert"
Last name: "Wesker"
Phone number:17367
it would only print the first Albert entered instead of both when I search for "Albert". Any ideas on how to change this?
#include <stdio.h>
#include <string.h>
#include "libpb.h"
void add_person(struct phone_book * pb, struct personal_info person)
{
int num = pb->num_people;
strcpy(pb->person[num].first, person.first);
strcpy(pb->person[num].last, person.last);
strcpy(pb->person[num].phone, person.phone);
num++;
pb->num_people = num;
}
void search_pb(struct phone_book pb, char find_name[])
{
int p;
for (p = 0; p < pb.num_people; p++)
{
if (strcmp(find_name, pb.person[p].first) == 0)
{
printf("\nName: %s %s\n", pb.person[p].first,
pb.person[p].last);
printf("Phone: %s\n", pb.person[p].phone);
return;
}
}
printf("No entries with that name. \n");
}
I was given the main function phone_book.c to work with so I just had to make the functions above and a header file:
#include <stdio.h>
#include <string.h>
#include "libpb.h"
int main ()
{
char cont;
char find_name[25];
struct phone_book pb;
pb.num_people = 0;
struct personal_info person;
printf("\n*********************************************\n");
printf("\n Start with entering new contacts! \n");
printf("\n*********************************************\n");
printf("\nWould you like to enter a new contact (Y/N): ");
while(pb.num_people < 20)
{
scanf("%c", &cont);
if (cont == 'Y')
{
printf("Enter a first name: ");
scanf("%s", person.first);
printf("Enter %s's last name: ", person.first);
scanf("%s", person.last);
printf("Enter %s's phone number: ", person.first);
scanf("%s", person.phone);
add_person(&pb, person);
}
else if (cont == 'N') break;
else if (cont == '\n') continue;
else printf("Error: User entered '%c'. Must enter either 'Y' or 'N'\n",
cont);
printf("\nWould you like to enter a new name (Y/N): ");
}
//search phone book by first name and print persons
printf("\n*********************************************\n");
printf("\n Now You can search for names! \n");
printf("\n*********************************************\n");
printf("\nWould you like to search for a name (Y/N)? ");
while(1)
{
scanf("%c", &cont);
if (cont == 'Y')
{
printf("Enter a person's name to search for: ");
scanf("%s", find_name);
//scanf("%c", &tmp);
search_pb(pb, find_name);
}
else if (cont == 'N') break;
else if (cont == '\n') continue;
else printf("Error: User entered '%c'. Must enter either 'Y' or 'N'\n",
cont);
printf("\nWould you like to search for a name (Y/N)? ");
}
return 0;
}
I also already made the necessary header file libpb.h:
#include<stdio.h>
#include<string.h>
#define MAX 20
#define _CRT_SECURE_NO_DEPRECATE
struct personal_info
{
char first[25];
char last[25];
char phone[15];
};
struct phone_book
{
struct personal_info person[MAX];
int num_people;
};
void add_person(struct phone_book *pb, struct personal_info person);
void search_pb(struct phone_book pb, char find_name[]);
A quick-and-dirty circumvention for this would be:
void search_pb(struct phone_book pb, char find_name[])
{
int matches = 0;
int p;
for (p = 0; p < pb.num_people; p++)
{
if (strcmp(find_name, pb.person[p].first) == 0)
{
printf("\nName: %s %s\n", pb.person[p].first,
pb.person[p].last);
printf("Phone: %s\n", pb.person[p].phone);
matches++;
}
}
if(matches == 0)
{
printf("No entries with that name. \n");
}
}
You could however, e.g. change search_pb() type to int, and return the match count after looping through, so that you can print "no matches" in the caller instead of printing them inside the function.

Fread() and fwrite () function

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>
void delay (int milliseconds); // for delay function
void menu (); //for choosing a menu
void addacc(); // for adding account
void view (); // for viewing existing list
struct date
{
int date, month, year; //struct for date
};
struct customer
{
char name[40],acctype[10];
int accno, age;
double phone;
float amount;
struct date dob; //calling other struct inside struct
struct date deposit;
struct date withdraw;
} add; //struct variable
void addacc()
{
FILE *fp;
fp=fopen ("cus.txt", "a+");
textcolor (1);
printf ("\n\t\t\t\t");
cprintf ("ADD RECORD");
printf("\n\n\n");
printf ("Enter today's date(date/month/year) \n");
scanf ("%d/%d/%d", &add.deposit.date, &add.deposit.month,&add.deposit.year);
printf ("Enter account number\n");
scanf ("%d", &add.accno);
printf ("Enter customer's name\n");
scanf ("%s", add.name);
printf ("Enter customer's age\n");
scanf ("%d", &add.age); printf ("Enter customer's phone num\n");
scanf ("%f",&add.phone);
printf ("Enter the account type(in words): \n\t 1:Current\n\t 2:Saving\n\t 3:Fixed\n");
scanf ("%s",&add.acctype);
textcolor (2);
cprintf ("Almost done! Just enter the amount you want to deposit: ");
scanf ("%f",&add.amount);
fwrite (&add,sizeof(add),1,fp);
fclose (fp);
}
void view ()
{
FILE *view;
int test=0;
system ("cls");
textcolor (3);
printf ("\n\t\t\t\t");
cprintf ("Customer's List");
printf ("\n\n\n");
textcolor(4);
cprintf ("\tCustomer's Name:");
cprintf ("\tAccount Number:");
cprintf ("\tCustomer's Phone No:");
view=fopen("cus.txt", "r");
while(fread(&add, sizeof(add),1,view)!=0)
{
printf ("%s", add.name);
printf ("%d", add.accno);
printf ("%f", add.phone);
test++;
}
fclose (view);
if (test==0)
{
printf ("NO RECORDS FOUND!");
}
}
void menu ()
{
int n;
printf ("Enter your choice 1, 2\n");
scanf ("%d", &n);
switch (n)
{
case 1:
addacc();
break;
case 2:
view ();
break;
}
}
void main (void)
{
system ("cls");
menu ();
}
Output: when you choose 1 as option
ADD RECORD
Enter today's date
Enter customer's name
etc
output: when you choose option 2 for viewing the list of existing customers
screen blank
So I would like to know is my syntax of fread wrong or of fwrite? why isn't it showing on the screen the entries which I just entered? I am using fread function for reading structures into the file and then I want to print the entries on the screen.
I removed the Windows-specific code and cleaned things up a bit. The code religiously checks whether each scanf() returned the correct value; lazily, it just exits if it doesn't. It also checks that the calls to fopen() work.
Some of the scanf() calls were dodgy. You don't need the & in front of a string name, and you do need %lf to read a double (the phone number — interesting choice of data type). I made sure that newlines appear in the output.
The printing is a bit better, though there are problems of a sort with long names.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void menu(void); // for choosing a menu
void addacc(void); // for adding account
void view(void); // for viewing existing list
struct date
{
int date, month, year; // struct for date
};
struct customer
{
char name[40], acctype[10];
int accno, age;
double phone;
float amount;
struct date dob; // calling other struct inside struct
struct date deposit;
struct date withdraw;
} add; // struct variable
void addacc(void)
{
FILE *fp = fopen("cus.txt", "a+");
if (fp == NULL)
exit(1);
printf("ADD RECORD\n");
printf("Enter today's date(date/month/year) \n");
if (scanf("%d/%d/%d", &add.deposit.date, &add.deposit.month, &add.deposit.year) != 3)
exit(1);
printf("Enter account number\n");
if (scanf("%d", &add.accno) != 1)
exit(1);
printf("Enter customer's name\n");
if (scanf("%s", add.name) != 1)
exit(1);
printf("Enter customer's age\n");
if (scanf("%d", &add.age) != 1)
exit(1);
printf("Enter customer's phone num\n");
if (scanf("%lf", &add.phone) != 1)
exit(1);
printf("Enter the account type(in words): \n\t 1:Current\n\t 2:Saving\n\t 3:Fixed\n");
if (scanf("%s", add.acctype) != 1)
exit(1);
printf("Almost done! Just enter the amount you want to deposit: ");
if (scanf("%f", &add.amount) != 1)
exit(1);
fwrite(&add, sizeof(add), 1, fp);
fclose(fp);
}
void view(void)
{
FILE *view;
int test = 0;
printf("Customer's List\n");
printf("\tCustomer's Name:");
printf("\tAccount Number:");
printf("\tCustomer's Phone No:\n");
view = fopen("cus.txt", "r");
if (view == NULL)
exit(1);
while (fread(&add, sizeof(add), 1, view) != 0)
{
printf("\t%16s", add.name);
printf("\t%15d", add.accno);
printf("\t%20.0f", add.phone);
putchar('\n');
test++;
}
fclose(view);
if (test == 0)
{
printf("NO RECORDS FOUND!");
}
}
void menu(void)
{
int n;
printf("Enter your choice 1, 2\n");
if (scanf("%d", &n) != 1)
exit(1);
switch (n)
{
case 1:
addacc();
break;
case 2:
view();
break;
}
}
int main(void)
{
menu();
return 0;
}
Sample output:
Enter your choice 1, 2
2
Customer's List
Customer's Name: Account Number: Customer's Phone No:
BushraYousuf 12345678 112345987621
PresidentBarackObama 987654321 2021199920
He's got more money stashed away than you have.

How to implement stacks using a structure while scanning from a file

#include <stdio.h>
#include <string.h>
typedef struct
{
int client_id;
char business_name [30];
char client_first_name [20];
char client_last_name [20];
char address [40];
float budget;
float energy_requirements;
char business_info [300];
}Client;
main()
{
Client c[20];
FILE*z;
void initialise (FILE*,Client []);
initialise (z,c);
system ("PAUSE");
}
void initialise(FILE*z,Client c[])
{
int x,max=20,top=-1;
if (top==max-1)
{
return;
}
top++;
for (x=0;x<20;x++)//Assigns all places in the structure to -1 and NULL
{
c[x].client_id=-1;
strcpy(c[x].business_name,"NULL");
strcpy(c[x].client_first_name,"NULL");
strcpy(c[x].client_last_name,"NULL");
strcpy(c[x].address,"NULL");
c[x].budget=-1;
c[x].energy_requirements=-1;
strcpy(c[x].business_info,"NULL");
}
z=fopen ("Novus.txt","r");
for (x=0;x<20;x++)//Replaces values in structure with data from text file
{
fscanf (z,"%d\n %[^\n]\n %[^\n]\n %[^\n]\n %[^\n]\n%f\n%f\n %[^\n]\n\n",&c[x].client_id,c[x].business_name,c[x].client_first_name,c[x].address,&c[x].budget,&c[x].energy_requirements,c[x].business_info);
}
fclose (z);
void menu (FILE*,Client []);
menu (z,c);
}
void menu (FILE*z,Client c[])
{
int choice;
do{
printf ("1.Add Client\n2.Change Client Information\n3.Delete Client\n4.Search Client\n5.Calculate Energy Requirements\n6.View Clients\n7.Terminate Program\nChoose an option from above:");
scanf ("%d",&choice);
}while (choice<1||choice>7);
if (choice==1)
{
system ("cls");
void accept (FILE*,Client []);
accept (z,c);
}
if (choice==2)
{
system ("cls");
void change (FILE*,Client []);
change (z,c);
}
if (choice==3)
{
system ("cls");
void destroy (FILE*,Client []);
destroy (z,c);
}
if (choice==4)
{
system ("cls");
void search (FILE*,Client []);
search (z,c);
}
if (choice==5)
{
system ("cls");
void energy (FILE*,Client []);
energy (z,c);
}
if (choice==6)
{
system ("cls");
void view (FILE*,Client []);
view (z,c);
}
if (choice==7)
{
system ("cls");
void end (FILE*,Client []);
end (z,c);
}
}
void accept (FILE*z,Client c[])//Accepts data from the user.
{
int max=20,top=-1;
int y=0,num,choice,choice2;
if (top==max-1)
{
return;
}
top++;
printf("How Many Clients Do You Want To Add:");
scanf ("%d",&num);
system ("cls");
while (y<num)
{
printf ("\nEnter Client ID:");
scanf ("%d",&c[y].client_id);
printf ("Enter Buisness Name:");
scanf (" %[^\n]",c[y].business_name);
printf ("Enter Client First Name:");
scanf (" %[^\n]",c[y].client_first_name);
printf ("Enter Client Last Name:");
scanf (" %[^\n]",c[y].client_last_name);
printf ("Enter Buisness Address:");
scanf (" %[^\n]",c[y].address);
printf ("Enter Client Budget:");
scanf ("%f",&c[y].budget);
printf ("Enter Client Energy Requirements:");
scanf ("%f",&c[y].energy_requirements);
printf ("Enter Buisness Information:");
scanf (" %[^\n]",c[y].business_info);
y++;
}
do {//Asks the user if they want to enter more data or terminate program.
printf ("\n\nDo You Want To:\n1.EnterMore Clients\n2.Continue\n");
scanf ("%d",&choice);
}while (choice<1 || choice>2);
if (choice==1)
{
void accept (Client []);
accept (c);
}
else if (choice==2)
{
do{
printf ("\n\nDo You Want To:\n1.Go Back To The Main Menu\n2.Exit\n");
scanf ("%d",&choice2);
}while (choice2<1 || choice2>2);
if (choice2==1)
{
void menu (Client[]);
menu (c);
}
else if (choice2==2)
{
void end (FILE*,Client []);
end (z,c);
}
}
}
I just wanted to find out if I am properly pushing data to the stack, and if I can scan the information from the file to the stack using the method above.
What I wanted to do was design a structure that can be used as a stack, and that can be populated using a pop function, such as that used in the initialise function. What my question is, is that I am fairly new to using stacks, and some times when I try to run my program using stacks, my antivirus program, Kaspersky, detects it as a Trojan Horse. What I wanted to know, is if I am implementing the stack correctly.
All errors have been addressed up to the point where you need to define the funcitons called in menu, etc... When building, make sure warnings are enabled gcc -Wall -Wextra -o yourprogram yourprogram.c at a minimum. In addition to the comment above, I have included comments inline below where attention is first needed. I have also provided the results of the current compile following the code. Finish defining the needed functions and then edit your question above and include any new problems you have run into. Good luck:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int client_id;
char business_name[30];
char client_first_name[20];
char client_last_name[20];
char address[40];
float budget;
float energy_requirements;
char business_info[300];
} Client;
int main () {
Client c[20];
FILE *z;
void initialise (FILE *, Client[]);
initialise (z, c);
system ("PAUSE");
return 0;
}
void initialise (FILE * z, Client c[]) {
int x;
int max = 20;
int top = -1;
if (top == (max - 1)) {
return;
}
top++;
for (x = 0; x < 20; x++) //Assigns all places in the structure to -1 and NULL
{
c[x].client_id = -1;
strcpy (c[x].business_name, "NULL");
strcpy (c[x].client_first_name, "NULL");
strcpy (c[x].client_last_name, "NULL");
strcpy (c[x].address, "NULL");
c[x].budget = -1;
c[x].energy_requirements = -1;
strcpy (c[x].business_info, "NULL");
}
z = fopen ("Novus.txt", "r");
for (x = 0; x < 20; x++) //Replaces values in structure with data from text file
{
fscanf (z,
"%d %[^\n]s %[^\n]s %[^\n]s %f %f %[^\n]s", /* format may need further help */
&c[x].client_id, c[x].business_name, c[x].client_first_name,
c[x].address, &c[x].budget, &c[x].energy_requirements,
c[x].business_info);
}
fclose (z);
void menu (FILE *, Client[]); /* must be previously declared/defined */
menu (z, c); /* you just closed 'z' two line up ?? */
}
void menu (FILE * z, Client c[]) {
int choice;
do {
printf
("1.Add Client\n2.Change Client Information\n3.Delete Client\n4.Search Client\n5.Calculate Energy Requirements\n6.View Clients\n7.Terminate Program\nChoose an option from above:");
scanf ("%d", &choice);
} while (choice < 1 || choice > 7);
if (choice == 1) {
system ("cls");
void accept (FILE *, Client[]); /* must be previously declared/defined */
accept (z, c);
}
if (choice == 2) {
system ("cls");
void change (FILE *, Client[]); /* must be previously declared/defined */
change (z, c);
}
if (choice == 3) {
system ("cls");
void destroy (FILE *, Client[]); /* must be previously declared/defined */
destroy (z, c);
}
if (choice == 4) {
system ("cls");
void search (FILE *, Client[]); /* must be previously declared/defined */
search (z, c);
}
if (choice == 5) {
system ("cls");
void energy (FILE *, Client[]); /* must be previously declared/defined */
energy (z, c);
}
if (choice == 6) {
system ("cls");
void view (FILE *, Client[]); /* must be previously declared/defined */
view (z, c);
}
if (choice == 7) {
system ("cls");
void end (FILE *, Client[]); /* must be previously declared/defined */
end (z, c);
}
}
void accept (FILE * z, Client c[]) //Accepts data from the user.
{
int max = 20;
int top = -1;
int y = 0, num, choice, choice2;
if (top == (max - 1)) {
return;
}
top++;
printf ("How Many Clients Do You Want To Add:");
scanf ("%d", &num); /* with multiple uses of scanf, you will need to flush the input buffer to */
system ("cls"); /* eliminate remaining '\n' chars that remain after the user presses 'Enter' */
while (y < num) { /* a simple 'int c;... do {c = getchar();} while (c != '\n'); after each scanf */
printf ("\nEnter Client ID:"); /* will suffice. (note 'c' is declared as an 'int' */
scanf ("%d", &c[y].client_id);
printf ("Enter Buisness Name:");
scanf (" %[^\n]", c[y].business_name);
printf ("Enter Client First Name:");
scanf (" %[^\n]", c[y].client_first_name);
printf ("Enter Client Last Name:");
scanf (" %[^\n]", c[y].client_last_name);
printf ("Enter Buisness Address:");
scanf (" %[^\n]", c[y].address);
printf ("Enter Client Budget:");
scanf ("%f", &c[y].budget);
printf ("Enter Client Energy Requirements:");
scanf ("%f", &c[y].energy_requirements);
printf ("Enter Buisness Information:");
scanf (" %[^\n]", c[y].business_info);
y++;
}
do { //Asks the user if they want to enter more data or terminate program.
printf ("\n\nDo You Want To:\n1.EnterMore Clients\n2.Continue\n");
scanf ("%d", &choice);
} while (choice < 1 || choice > 2);
if (choice == 1) {
accept (z, c);
} else if (choice == 2) {
do {
printf
("\n\nDo You Want To:\n1.Go Back To The Main Menu\n2.Exit\n");
scanf ("%d", &choice2);
} while (choice2 < 1 || choice2 > 2);
if (choice2 == 1) {
menu (z, c);
} else if (choice2 == 2) {
end (z, c);
}
}
}
Current Compiler Errors:
$ gcc -Wall -Wextra -o bin/addrstack addrstack.c
addrstack.c: In function ‘accept’:
addrstack.c:148:17: warning: implicit declaration of function ‘end’ [-Wimplicit-function-declaration]
end (z, c);
^
addrstack.c:97:18: note: previous declaration of ‘end’ was here
void end (FILE *, Client[]); /* must be previously declared/defined */
^
addrstack.c:148:17: error: incompatible implicit declaration of function ‘end’
end (z, c);
^
addrstack.c:97:18: note: previous implicit declaration of ‘end’ was here
void end (FILE *, Client[]); /* must be previously declared/defined */
I use the following codes for generic stack for any type.
In the example, I create a stack of int. Yet you can typedef your type to a name, and use DeclareStackType(YourType) to declare a data structure for the stack, and then use stack__YourType foo; to declare the stack. See test code for detail.
#include <malloc.h>
#define DeclareStackType(ValueType) \
typedef struct { \
int size; \
ValueType *buf; \
int index; \
} stack_ ## ValueType
#define InitStack(stack, ValueType, sz) do {stack.size = sz; stack.buf=(ValueType*)malloc(sizeof(ValueType)*sz); stack.index = 0;} while (0)
// this re-uses the already initialized buffer. Just reset index to zero.
#define ClearStack(stack) do {stack.index = 0;} while(0)
#define PushStack(stack, value) do {stack.buf[stack.index++] = value; } while(0)
#define PopStack(stack) (stack.buf[--stack.index])
#define IsStackFull(stack) (stack.index == stack.size)
#define IsStackEmpty(stack) (stack.index == 0)
#define PushStackSafe(stack, value) do {if (!IsStackFull(stack)) stack.buf[stack.index++] = value;} while(0)
#define PopStackSafe(stack) (stack.buf[IsStackEmpty(stack)? 0 : (stack.index -= 1)])
// -------- test codes (in C++, since C++ can compile C program, I am lazy to do C printf...)---------------
#include <iostream>
DeclareStackType(int);
stack_int my_integer_stack;
using namespace std;
int main(int argc, char *argv[])
{
InitStack(my_integer_stack, int, 5);
if (IsStackEmpty(my_integer_stack)) {
cout << "1. stack empty now" << endl;
}
PushStack(my_integer_stack, 1);
PushStack(my_integer_stack, 2);
ClearStack(my_integer_stack); // clear the above input
if (IsStackEmpty(my_integer_stack)) {
cout << "2. stack empty now" << endl;
}
PushStack(my_integer_stack, 3);
PushStack(my_integer_stack, 5);
PushStack(my_integer_stack, 1);
PushStack(my_integer_stack, 2);
PushStackSafe(my_integer_stack, 8);
if (IsStackFull(my_integer_stack)) {
cout << "3. stack full now" << endl;
}
PushStackSafe(my_integer_stack, 9); // won't push
cout << PopStack(my_integer_stack) << endl;
cout << PopStack(my_integer_stack) << endl;
cout << PopStack(my_integer_stack) << endl;
cout << PopStack(my_integer_stack) << endl;
cout << PopStack(my_integer_stack) << endl;
if (IsStackEmpty(my_integer_stack)) {
cout << "4. stack empty now" << endl;
}
cout << PopStackSafe(my_integer_stack) << endl; // pop will not go to index -1, yet it returns buf[0] in the stack
}

Why is my static stack not working?

static stack implementation
this is also not deleting according to the lifo principle
static stack implementation:
it is not taking name for the second time
this is the new code now tell me why is it not working
please help
typedef struct student {
char name[20];
int roll;
int age;
} mystruct;
#define size 40
int top;
static mystruct s[size];
void push()
{
if (top == size - 1) {
printf("\noverflow"); //
} else {
printf("\nenter the name of the student");
gets(s[top].name);//not taking name for d 2 time
printf("\nenter the roll number");
scanf("%d", &s[top].roll);
printf("\nenter the age of the student");
scanf("%d", &s[top].age);
++top;
}
}
void pop()
{
if (top == -1)
{
printf("\nunderflow");
} else {
printf("%s", s[top].name);
printf("%d", s[top].roll);
printf("%d", s[top].age);
printf("\npopped");
--top;
}
}
void display()
{
int i;
if (top == -1) {
printf("\nstack is empty");
} else {
for (i = top; i > 0; i--) {
printf("\nthe name of the student is%s", s[top].name);
}
printf("\nthe roll no of the student is%d", s[top].roll);
printf("\nthe age of the student is%d", s[top].age);
}
}
main()
{
top = -1;
char ch;
while (1) {
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = getche();
if (ch == '0') {
break;
}
switch (ch) {
case '1':
push();
break;
case '2':
pop();
break;
case '3':
display();
break;
default:
printf("choice not valid");
break;
}
}
}
The first problem I noticed was that top is initialized to -1. Trying to access the member data of s[top] when top is initialized to -1 will result in unpredictable behavior.
I would suggest changing the line
top = -1;
to
top = 0;
That changes the basic assumption you have made in push, pop, and display about when the stack is empty and when it is full. Instead of checking if ( top == -1 ), you have to now check if (top == 0 ). Instead of checking if ( top == size - 1 ), you have to now check if ( top == size ).
In pop, you have to use top-1 instead of top.
The for loop in display is not scoped correctly. You need to use:
for (i = top-1; i >= 0; i--) {
printf("\nthe name of the student is %s", s[i].name);
printf("\nthe roll no of the student is %d", s[i].roll);
printf("\nthe age of the student is %d", s[i].age);
}
Also, reading the options for the menu and reading the subsequent input is little bit tricky.
After you read the menu option, you have to make sure that you eat up all the input until the next newline. Otherwise, gets() will read everything after your menu option until the end of the line. If you typed 1 for the menu and then typed Return/Enter, the name will be automatically accepted as "\n". Hence, I suggest the lines:
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = fgetc(stdin);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
Also, after you read the age of the object, you have to eat everything up to the newline. Otherwise, the newline character is read in as the choice for the next menu option.
scanf("%d", &s[top].age);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
Here's the fully working file. I have replaced gets by fgets and getche by fgetc.
#include <stdio.h>
#include <string.h>
typedef struct student {
char name[20];
int roll;
int age;
} mystruct;
#define size 40
int top;
static mystruct s[size];
void push()
{
if (top == size) {
printf("\noverflow"); //
} else {
printf("\nenter the name of the student: ");
fgets(s[top].name, 20, stdin);//not taking name for d 2 time
// The newline character is part of s[top].name when fgets is
// finished. Remove that.
s[top].name[strlen(s[top].name)-1] = '\0';
printf("\nenter the roll number: ");
scanf("%d", &s[top].roll);
printf("\nenter the age of the student: ");
scanf("%d", &s[top].age);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
++top;
}
}
void pop()
{
if (top == 0)
{
printf("\nunderflow");
} else {
printf("%s, ", s[top-1].name);
printf("%d, ", s[top-1].roll);
printf("%d", s[top-1].age);
printf("\npopped");
--top;
}
}
void display()
{
int i;
if (top == 0) {
printf("\nstack is empty");
} else {
for (i = top-1; i >= 0; i--) {
printf("\nthe name of the student is %s", s[i].name);
printf("\nthe roll no of the student is %d", s[i].roll);
printf("\nthe age of the student is %d", s[i].age);
}
}
}
main()
{
top = 0;
char ch;
while (1) {
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = fgetc(stdin);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
if (ch == '0') {
break;
}
switch (ch) {
case '1':
push();
break;
case '2':
pop();
break;
case '3':
display();
break;
default:
printf("choice, %c, not valid", ch);
break;
}
}
}
You need to change getche() to getchar()
Note: getche() is a non-standard function.
Maybe this will be useful http://www.delorie.com/djgpp/doc/libc/libc_385.html
Pay attention to implementation note:
"If you can detect the situation when one of the conio functions is called for the very first time since program start, you could work around this problem by calling the gppconio_init function manually"
or just replace it with getchar(). And there meaned conio included.

How to check whether ID already exists in File with C Programming

I have this coding down below (just posting the Customers Management only).
This a database in which I am adding a customer each time it passes. Now I need to check whether the c.ID which is the client ID exists or not.
I tried doing a method called searchID which returns 1 if it's found or -1 if it's not found.
Problem is when I try to run the program, the program literally hangs there. Whether I press 23 or "ENTER" nothing happens and I would need to exit it using the CTRL + C;
so this is how it works:
When I add a customer (Which is a struct) it saves into the file but I first need to check
whether the ID exists in the database or not otherwise I need to ask the user to either input another ID or go back to the Main Menu
Any suggestions please?? thank you
#include<io.h>
#include<fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "..\Headers\common.h"
#include "..\Headers\customerManagement.h"
static FILE *cfp;
static customer c;
#define STRUCTSIZE sizeof (customer)
/** This is the Customers's Main Menu in which the various sections can be
* accessed from here
*/
boolean customerMainMenu()
{
int optionC;
clrscr();
copyright();
printf ("\n\n\n\n\t\t ************* Customer's Main Menu *************\n \n \n");
printf ("Press [1] to add a new Customer\n");
printf ("Press [2] to edit a Customer\n");
printf ("Press [3] to list all Customers\n");
printf ("Press [4] to Show a Customer's last Order\n");
printf ("Press [5] to go back to Main Menu\n\n\n");
if (scanf ("%d",&optionC) == 1)
{
switch (optionC)
{
case 1:
{
clrscr();
getchar();
addCustomer();
break;
}
case 2:
{
printf ("Edit a Customer\n");
break;
}
case 3:
{
clrscr();
listCustomers();
getchar();
while (getchar()!='\n')
{
}
break;
}
case 4:
{
printf ("Customer's Last Order\n");
break;
}
case 5:
{
system ("PAUSE");
break;
}
default:
{
if (optionC != 1 || optionC != 2 || optionC != 3 || optionC != 4 || optionC !=5)
{
clrscr();
printf ("Invalid option!\n");
system ("PAUSE");
customerMainMenu();
}
break;
}
}
}
return TRUE;
}
/**
* This following method will append a customer to the
* database at the end of the file
*
* */
void addCustomer ()
{
char ch;
copyright();
printf ("\n\n\n\n\t\t ************* Add Client **********\n \n \n");
if ((cfp = fopen ("customers.dat","a+b")) == NULL)
{
fputs("Can't open customers.dat file\n",stderr);
}
printf ("\tThis will add another customer to the the database\n");
printf ("\tPress 'Y' to confirm or 'N' to return to the Client Main Menu\n\tWITHOUT adding a customer\n");
ch = getchar();
if (ch == 'n' || ch == 'N')
{
customerMainMenu();
}
else if (ch == 'y' || ch == 'Y')
{
clrscr();
printf ("\n\n\n\n\t\t ************* Add Client **********\n \n \n");
printf ("Please enter Name:\n");
while (scanf ("%s", c.name) == 0 || cCheck(c.name,100) == FALSE);
{
}
printf ("Please Enter Surname: \n");
while (scanf ("%s",c.surname) == 0 && cCheck (c.surname,100) == FALSE);
{
}
printf ("Please Enter ID Card, [NOTE! Only numbers are allowed!]\n");
int cID;
cID = 0;
while (scanf ("%d",&cID)==0)
{
printf ("Only Numbers are allowed!\n");
while (getchar() != '\n')
{
}
}
if (searchID(cID) == 1)
{
printf ("This ID already exists. Client already exists!\n");
printf ("Do you want to input another ID or return to Main Menu?\n");
printf ("Press 'Y' if you enter another ID, press any other key to return to Main Menu\n:");
ch = getchar();
if (ch == 'y' || ch == 'Y')
{
printf ("Enter another ID:\n");
while (scanf ("%d",&cID)==0)
{
printf ("Only Numbers are allowed!\n");
while (getchar() != '\n')
{
}
}
searchID(cID);
}
else if (searchID(cID) == -1)
{
cID = c.ID;
getchar();
}
}
while (getchar()!='\n')
{
}
printf ("Please Enter Address:\n");
gets(c.address);
fwrite (&c,STRUCTSIZE, 1, cfp);
printf ("For Testing purposes:\n");
printf (" %s\n %s\n %s\n %d\n", c.name, c.surname, c.address, c.ID);
askAnother();
}
else
{
printf ("\nInvalid choice! Either Y or N is accepted\n");
system ("PAUSE");
getchar();
addCustomer();
}
}
void listCustomers()
{
if ((cfp = fopen ("customers.dat","rb")) == NULL)
{
fputs("Can't open customers.dat file\n",stderr);
printf ("Returning to Customer Main Menu");
system ("PAUSE");
customerMainMenu();
}
rewind (cfp);
while (fread (&c,STRUCTSIZE,1,cfp)==1)
{
printf ("Customer: %s %s ID: %d\n", c.surname, c.name, c.ID);
}
fclose (cfp);
// system ("PAUSE");
}
void askAnother()
{
printf ("Do you want to add another Customer?\n");
printf ("Enter 'Y' for yes and 'N' to return to the Main Menu\n");
char input;
input = getchar();
if (input == 'Y' || input == 'y')
{
getchar();
addCustomer();
}
else if (input == 'N'|| input == 'n')
{
fclose (cfp);
customerMainMenu();
}
else
{
printf ("Invalid Option! Only Y or N are allowed\n");
system ("PAUSE");
askAnother();
}
}
boolean cCheck(char *test, int max)
{
int x;
for (x =0; x<max; x++)
{
if (isdigit(test[x]))
{
return FALSE;
}
if (x==max)
{
return TRUE;
}
x++;
}
return TRUE;
}
int fileSize()
{
int lengthOfFile;
int file;
file = open("Customers.dat",O_RDONLY,0);
lengthOfFile = lseek (file,0, SEEK_END);
return lengthOfFile;
}
int getNoOfRecords()
{
return (fileSize()/(STRUCTSIZE));
}
/**
* This method will compare the ID passed from the ID of the customer to check
* whether it is exists or not. If it exists it will output 1 otherwise it
* will output -1. This will make sure that the Person's ID is unique
*
*/
int searchID (int cID)
{
// for the while loop
int index;
index = 0;
//gets the number of records currently held in the file.
int records;
records = getNoOfRecords();
//User will input the ID into this variable and it will be checked
//whether it exists or not
int IDstatus;
IDstatus = 0;
while (index != records)
{
fread (&c,STRUCTSIZE,1,cfp);
if (c.ID == cID)
{
IDstatus = 1;
}
else
{
IDstatus = -1;
}
}
return IDstatus;
}
EDIT:
There are either 2 things:
Either the Method is not working the SearchID() method because even though I have 2 IDs which are 0 now, they are still accepting it
or else because of the c.ID which is staying 0.
When I'm inputting the data, it is accepting it BUT when I try to output the whole record, the Client ID stays 0.
Added to that, it IS letting me having Two IDs which are 0 so most probably the method is not working.... Thanks for all the help until now!
You missed to increment index, and of course you should exit the loop when you found the id:
while (index != records)
{
fread (&c,STRUCTSIZE,1,cfp);
if (c.ID == cID)
{
IDstatus = 1;
break; // <<<< otherwise IDStatus will be overwritten by next iteration
}
else
{
IDstatus = -1;
}
index++; // <<< otherwise endless loop
}

Resources