new to programming here :3
(Don't check my profile, I actually only know C, for now...)
I need help here, I dunno what's causing the problem, but whenever I repeat the program, it skips asking for a replacement value in
char C1.name
in function
void Name()
{
p("ENTER NAME: ");
gets(C1.name);
p("CONTACT DETAILS: ");
s("%d", &C1.cont_no);
}
in my Program
#include <stdio.h>
#include <windows.h>
#define p printf
#define s scanf
void Name();
void Order();
void Total();
void Receipt();
char Repeat();
/* CUSTOMER DETAILS */
struct CustomerOrder
{
char name[50];
long int cont_no;
int qty;
float price, total;
} C1;
main()
{
char cont;
/* Program Process... */
do{
Name();
Order();
Total();
Receipt();
cont = Repeat();
}while(cont == 'Y');
}
void Name()
{
/* ENTER NAME AND CONTACT DETAILS */
p("ENTER NAME: ");
gets(C1.name);
p("CONTACT DETAILS: ");
s("%d", &C1.cont_no);
}
void Order()
{
/* ENTER ORDERS */
p("HOW MANY ORDERS: ");
s("%d", &C1.qty);
C1.price = 59.99;
}
void Total()
{
/* TOTAL */
C1.total = C1.price * C1.qty;
p("TOTAL IS: %.2f", C1.total);
system("pause");
}
void Receipt()
{
system("cls");
/*PRINTED RECEIPT SAMPLE */
p("NAME IS: %s\n", C1.name);
p("CONTACT DETAILS: %d\n", C1.cont_no);
p("QTY: %d\n", &C1.qty);
p("PRICE EACH: %.2f\n", C1.price);
p("TOTAL PAYOUT: %.2f\n", C1.total);
}
char Repeat()
{
/* ASKS USER TO REPEAT PROGRAM, THEN RETURN VALUE TO BE USED BY function
main */
char repeat;
p("REPEAT?: ");
s("%s", &repeat);
return repeat;
}
There may be other problems you would probably notice (which I dunno if there are, but I would like it NOT to skip the Name part and stuff...
You only want to get a character when asking the user to repeat so change
s("%s", &repeat);
to
s(" %c", &repeat);
if you add a space ^ you will skip the \n that you entered previously.
Related
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include <time.h>
struct customer
{
char name[45];
char invoice[4];
char service[2];
char carNo[16];
char fee[3];
bool urgent;
time_t date;
};
/*********************************************************************************************/
void toFile(char*); // will pass string (char*) to it and itll write it to record.txt - DONE
void displayMenu(void); // will display the menu - DONE
void newInvoice(int invoiceNo);
/*********************************************************************************************/
int main()
{
char toContinue;
int invoiceNo =1;
// format of invoices in txt file
do
{
newInvoice(invoiceNo);
invoiceNo += 1;
// asking if user wants to continue to another order or close the program
printf("Do you want to continue? (Y or N) :");
scanf(" %c",&toContinue);
}
while (toContinue !='N' && toContinue !='n');
return 0;
}
/*********************************************************************************************/
void newInvoice(int invoiceNo)
{
// variable declaration
char enter,urgentCH;
int feeINT;
struct customer *newCus;
newCus = (struct customer*) malloc ( sizeof(struct customer));
displayMenu();
enter = fgetc(stdin);
sprintf(newCus->invoice, "%d", invoiceNo);
// customer info being collected
printf("Customer Name:\n");
scanf("%[^\n]%*c", newCus->name);
printf("Vehicle Numb :\n");
scanf("%[^\n]%*c", newCus->carNo);
printf("Service Selection Numb (From Menu):\n");
scanf("%[^\n]%*c", newCus->service);
printf("Urgent? (Y or N ):\n");
scanf(" %c",&urgentCH);
if(urgentCH == 'Y' || urgentCH == 'y')
newCus->urgent = true;
else
newCus->urgent = false;
printf("Fee (from menu):");
scanf("%d",&feeINT);
sprintf(newCus->fee, "%d", feeINT);
time(&newCus->date); // system date and time being taken
// writng to file
toFile("Invoice:\t");
toFile(newCus->invoice);
toFile(" customer: ");
toFile(newCus->name);
toFile(" vehicle: ");
toFile(newCus->carNo);
toFile(" service: ");
toFile(newCus->service);
toFile(" type: ");
if(newCus->urgent)
toFile("urgent");
else
toFile("normal");
toFile(" fee: ");
toFile(newCus->fee);
toFile(" date: ");
toFile(ctime(&newCus->date));
// invoice output
printf("Customer:%s\n vehicle:%s\n Service:%s\n type:%s\n Fee:%s\n Date:%s\n",
newCus->name,newCus->carNo,newCus->service,newCus->urgent?"urgent":"normal",newCus->fee,ctime(&newCus->date));
free(newCus);
}
/*********************************************************************************************/
void displayMenu()
{
printf("Numb Service type Time service fee\n");
printf(" (minutes) Normal Urgent\n");
printf("1 Repair punctured car tyre/piece 10 5 6\n");
printf("2 Car tyre change /piece 15 150 160\n");
printf("3 Mineral Oil Change 20 80 90\n");
printf("4 Synthetic Oil Change 10 130 140\n");
printf("5 Battery Change 5 200 210\n");
printf("6 Head light bulb change /piece 5 6 8\n");
printf("7 Taillight bulb change /piece 5 6 8\n");
printf("8 Car Wash 10 10 12\n");
printf("------------PRESS ANYTHING TO CONTINUE------------\n");
}
/*********************************************************************************************/
void toFile(char* Str2Write)
{
// file opened for writing
FILE *file2write;
file2write = fopen("file.txt","a");
// file opened successfully check
if(file2write == NULL)
exit(1);
// writng
fprintf(file2write,"%s",Str2Write);
// fprintf(fptr,"\n");
// closing
fclose(file2write);
}
/*********************************************************************************************/
The problem is in
void newInvoice(int invoiceNo)
{
// variable declaration
char enter,urgentCH;
int feeINT;
struct customer *newCus;
newCus = (struct customer*) malloc ( sizeof(struct customer));
displayMenu();
enter = fgetc(stdin);
sprintf(newCus->invoice, "%d", invoiceNo);
// customer info being collected
printf("Customer Name:\n");
scanf("%[^\n]%*c", newCus->name);
printf("Vehicle Numb :\n");
scanf("%[^\n]%*c", newCus->carNo);
printf("Service Selection Numb (From Menu):\n");
scanf("%[^\n]%*c", newCus->service);
printf("Urgent? (Y or N ):\n");
scanf(" %c",&urgentCH);
if(urgentCH == 'Y' || urgentCH == 'y')
newCus->urgent = true;
else
newCus->urgent = false;
printf("Fee (from menu):");
scanf("%d",&feeINT);
sprintf(newCus->fee, "%d", feeINT);
time(&newCus->date); // system date and time being taken
This part is giving a weird output:
I'm very new to this. I was told that scanf is a risky command but I don't know how to replace it with something else.
You are right you should probably not use scanf instead use fgets.
Try building off of this code example:
void newInvoice(int invoiceNo)
{
// Input Variable
char userInput[100];
// You make this not a pointer since in
// original code you don't return it anywhere
// and you don't have to deal with managing memory leaks that you were having.
Customer newCustomer;
// COPY PASTE THIS FROM HERE
printf("Customer Name: "); // query for user input
fgets(userInput, sizeof(userInput), stdin); // get the input
userInput[strlen(userInput) - 1] = '\0'; // removes the \n at end when the user press enter
strcpy(newCustomer.name, userInput); // copy userInput into struct
// TO HERE
printf("You Inputted: %s\n", userInput);
// add more options here
}
Example output for running this should be:
Customer Name: David
You Inputted: David
Do you want to continue? (Y or N) :n
Also use the definition of:
typedef struct customer
{
char name[45];
char invoice[4];
char service[2];
char carNo[16];
char fee[3];
bool urgent;
time_t date;
}Customer;
So you don't have to say struct customer every time. Just makes your code look cleaner.
I'm brand new to C and I'm trying to figure out what in the world is causing this. Another similar question said that I had to download another library but that hasn't fixed the issue. So, hopefully someone can spot my problem.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum Subject {SER=0, EGR=1, CSE=2, EEE=3} subject;
struct Course {
enum Subject subject;
int number;
char teacher[1024];
int hours;
} *course;
//place to store course information
struct Course* CourseCollection = NULL;
//number of courses in the collection. also the index of the next empty element.
int courseCount = 0;
void branching(char option);
void course_insert(struct Course course);
int main() {
char input_buffer;
printf("Welcome to ASU Class Schedule\n");
//menu and input loop
do {
printf("\nMenu Options\n");
printf("------------------------------------------------------\n");
printf("a: Add a class\n");
printf("d: Drop a class\n");
printf("s: Show your classes\n");
printf("q: Quit\n");
printf("\nTotal Credits: %d\n\n", courseCount);
printf("Please enter a choice ---> ");
scanf(" %c", &input_buffer);
branching(input_buffer);
} while (input_buffer != 'q');
return 0;
}
//takes a character representing an inputs menu choice and calls the appropriate
//function to fulfill that choice. display an error message if the character is
//not recognized.
void branching(char option) {
int prefix, courseNum, credits;
char instructor;
struct Course course1;
switch(option) {
case 'a' :
printf("Adding a class");
printf("\nWhat is the subject (SER=0, EGR=1, CSE=2, EEE=3)? ");
scanf(" %d", &prefix);
course1.subject = prefix;
printf("\nWhat is the course number (e.g. 334)? ");
scanf(" %d", &courseNum);
course1.number = courseNum;
printf("\nHow many credits is the class? ");
scanf(" %d", &credits);
course1.hours = credits;
printf("\nWhat is the name of the teacher? ");
scanf(" %s", &instructor);
strlcpy(course1.teacher, instructor, 1024);
printf(" %s %d", course1.subject, course1.number);
courseCount++;
course_insert(course1);
break;
case 'd' :
// TODO
break;
case 's' :
// TODO
break;
case 'q' :
printf("Goodbye ");
break;
default :
printf("Error: Invalid Input. Please Try Again. ");
break;
}
void course_insert(struct Course course) {
CourseCollection = malloc(sizeof(course)*courseCount);
}
}
The problem is a syntactical bug; the function definition for course_insert() is inside the curly braces of the function definition of branching(). You need to fix the curly braces:
void branching (char option)
{
// Code for function
}
void course_insert(struct Course course)
{
CourseCollection = malloc(sizeof(course)*courseCount);
}
I am creating a program, about seat reservations. I was asked to use unsigned short and unsigned int for some of the variables, so that is why they are set like that.
I have a program that works ok. But when I transfer everything inside a function, everything seems to work ok, but inside my structure weird values start to be saved all over the place..
I only want to save the values of the file (from line 2 -> the end of file).
Because I have a structure that to be initialized I have first to read the txt file and numberofseats, I have am declaring this variable (passenger) 2 times..inside the function (local var) and in the main body..
Maybe this causes the problem?
If I don't use a function everything work fine!
So the problematic code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int i,j,numberofseats,temp;
char platenr[8],selection,buff[60];
char firstname[20];
char lastname[20];
char phone[11];
char *p;
typedef struct
{
char fullname[40];
unsigned short phonenr[10];
unsigned int seatnr;
}PASSENGERS;
void readfile( void)
{
FILE *businfo;
businfo = fopen ("bus.txt","r");
if (businfo == NULL)
{
printf("Error Opening File, check if file bus.txt is present");
exit(1);}
else
{
fscanf(businfo,"%s %d",platenr, &numberofseats);
printf("Bus Licence plate Nr is: %s and number of seats is: %d", platenr, numberofseats);
PASSENGERS passenger[numberofseats];
for (j=0;j<numberofseats;j++)
{passenger[j].seatnr=j+1;
strcpy(passenger[j].fullname,"\0");
}
while (fgets(buff,sizeof(buff),businfo)!=0)
{sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
strcpy(passenger[temp-1].fullname,firstname);
strcat (passenger[temp-1].fullname, " ");
strcat(passenger[temp-1].fullname,lastname);
printf("%s",passenger[temp-1].fullname);
i=0;
for (p=phone;*p!='\0';p++)
{
(passenger[temp-1].phonenr[i])=*p -'0';
i++;
}
}
}
}
int main(void)
{
readfile();
PASSENGERS passenger[numberofseats];
A variable called x in function foo has nothing to do with a variable called y in function bar. In other words: passenger in main and passenger in readfile are different variables. Changing one will not impact the other.
What you want is probably more like this:
int main(void)
{
PASSENGERS passenger[numberofseats];
readfile(passenger);
^^^^^^^^^
Pass array as a pointer
....
}
and
void readfile(PASSENGERS* passenger)
{
....
// REMOVE THIS: PASSENGERS passenger[numberofseats];
}
Beside that notice:
// Global variables gets zero initialized
int i,j,numberofseats,temp;
^^^^^^^^^^^^
Becomes zero at start up
but still you use it in main:
PASSENGERS passenger[numberofseats];
That is probably no what you really want.
Since you try to read the number of seats in the function, it seams you really want to use dynamic memory allocation. Like:
PASSENGERS* readfile()
{
.....
.....
PASSENGERS* p = malloc(numberofseats * sizeof(PASSENGERS));
.....
.....
return p;
}
int main(void)
{
PASSENGERS* passenger = readfile();
.....
.....
free(passenger);
return 0;
}
If you don't want dynamic allocation, you must move the input of numberofseats into main so it is done before declaring the array.
The problem is that you are declaring a local array in the function readfile(), and once this function terminates, it is lost. You need to be able to return the changes to main(). For that you have some options. One is that you may declare the array in main(), and change your function to void readfile(PASSENGERS passenger[]). In this case, you will do something like this:
int main()
{
PASSENGERS passenger[numberofseats];
readfile(passenger);
// more code
You will be basically passing a pointer to the memory location of the elements stored in the array, local to main(), and the function will fill the array, effectively returning the changes.
Another option is to dynamically allocate an array (with malloc() family) in the function, and make it return a pointer like PASSENGERS *readfile(void). This option may be more suitable if the number of seats is not known at compile time, so you need to dynamically grow or shrink the array when necessary. This option however, leaves you the burden of managing the memory manually, like free()'ing the allocated memory when you are done.
Since you say that you will read numberofseats from the file, the latter would be the better idea, so your code will look something like this:
PASSENGERS *readfile(void)
{
FILE *businfo;
PASSENGERS *passenger;
businfo = fopen ("bus.txt","r");
// do the checks, read the numberofseats
passenger = malloc(numberofseats * sizeof *passenger);
// read the values, fill the array
fclose(businfo); // do not forget to close the file
return passenger;
}
int main()
{
PASSENGERS *passenger = readfile();
// more code
free(passenger);
return 0;
}
Ok, so what I did, before starting to work on dynamic allocation is specify the max number of seats in the start of main, and from there I finished my code as follows. I have 2 warning messages though in lines 43, 109 that can't seem to be able to fix.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int i,j,numberofseats,temp;
char platenr[8],selection;
char firstname[20],lastname[20];
char phone[11];
char *p;
typedef struct
{
char fullname[40];
unsigned short phonenr[10];
unsigned int seatnr;
}PASSENGERS;
void readfile(PASSENGERS passenger[])
{ char buff[60];
FILE *businfo;
businfo = fopen ("bus.txt","r");
if (businfo == NULL)
{
printf("Error Opening File, check if file bus.txt is present");
exit(1);}
else
{
fscanf(businfo,"%s %d",platenr, &numberofseats);
printf("Bus Licence plate Nr is: %s, and Number of Seats is: %d.", platenr, numberofseats);
for (j=0;j<numberofseats;j++)
{passenger[j].seatnr=j+1;
strcpy(passenger[j].fullname,"\0");
}
while (fgets(buff,sizeof(buff),businfo)!=0)
{sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
strcpy(passenger[temp-1].fullname,firstname);
strcat (passenger[temp-1].fullname, " ");
strcat(passenger[temp-1].fullname,lastname);
i=0;
for (p=phone;*p!='\0';p++)
{
(passenger[temp-1].phonenr[i])=*p -'0';
i++;
}
}
}
}
void countfreeseats(PASSENGERS passenger[]){
int freeseats = 0;
for (j=0; j<numberofseats; j++)
{
strcmp(passenger[j].fullname,"\0")==0 ? freeseats = freeseats + 1 : freeseats ;}
printf ("There are %d Free Seats in this Bus. \n", freeseats);
printf("Seats that are Available are:\n");
for (j=0; j<numberofseats; j++)
{if (strcmp(passenger[j].fullname,"\0")==0)
printf ("%u\n", passenger[j].seatnr);
}
freeseats = 0;
}
void changeData(PASSENGERS *target){
unsigned short tempdigit;
printf("Enter Passenger's first name:");
scanf("%s",firstname);
printf("Enter Passenger's last name:");
scanf("%s",lastname);
strcpy(target->fullname,firstname);
strcat (target->fullname, " ");
strcat(target->fullname,lastname);
printf("Enter Passenger's phone Nr:");
scanf("%s",phone);
i=0;
for (p=phone;*p!='\0';p++)
{
(target->phonenr[i])=*p -'0';
i++;
}
}
void searchpassenger(PASSENGERS passenger[], char selection)
{ char tempsel,tmpfirst[20],tmplast[20];
unsigned short tempphone[10];
if (selection == '1')
{ printf("Enter Passenger's first name:");
scanf("%s",tmpfirst);
printf("Enter Passenger's last name:");
scanf("%s",tmplast);
strcat (tmpfirst, " ");
strcat(tmpfirst,tmplast);
for (j=0;j<numberofseats;j++)
if (strcmp(passenger[j].fullname,tmpfirst)==0)
printf ("Passenger %s has Seat Nr #: %u\n",tmpfirst,passenger[j].seatnr);
}
else if (selection == '2')
{ printf("Enter Passenger's Phone Nr:");
scanf("%s",phone);
i=0;
for (p=phone;*p!='\0';p++)
{
(tempphone[i])=*p -'0';
i++;
}
for (j=0;j<numberofseats;j++)
{if (strcmp(tempphone,passenger[j].phonenr)==0)
printf("Passenger %s has Seat Nr %hd already Booked",passenger[j].fullname,passenger[j].seatnr);
}
}
}
void cancelSeat(PASSENGERS *target){
strcpy(target->fullname,"\0");
for (i=0;i<10;i++)
target->phonenr[i]=0;
printf("Seat Nr %d is now Free",temp);
}
void showList(PASSENGERS passenger[])
{
printf("The following Seats are Booked: \n Name, PhoneNr, SeatNr\n\n"); /*Emfanisi minimatos*/
for (i=0; i<numberofseats; i++)
if (strcmp(passenger[i].fullname,"\0")!=0)
{
printf("%s, ",passenger[i].fullname);
for (j=0;j<10;j++)
{printf("%hu",passenger[i].phonenr[j]);}
printf(", %u\n",passenger[i].seatnr);
}
}
void writeFile(PASSENGERS passenger[])
{
FILE * output; /* Dilosi onomatos arxeiou */
output = fopen("output.txt","w"); /*dimiourgia i eggrafi pano se iparxon arxeio me onoma output.txt, mesw tis parametrou w*/
fprintf(output,"%s %d \n",platenr,numberofseats); /* mesw tis fprintf eksagogi pinakidas kai epikefalidas "Diagramma leoforeiou" sto arxeio output.txt. Allagi grammis opou xreiazetai*/
for (i=0; i<numberofseats; i++)
{if (strcmp(passenger[i].fullname,"\0")!=0)
{
fprintf(output,"%s ",passenger[i].fullname);
fprintf(output,"%u ",passenger[i].seatnr);
for (j=0;j<10;j++)
fprintf(output,"%hu",passenger[i].phonenr[j]);
fprintf(output,"%s","\n");
}
}
fclose(output); /* Kleisimo arxeiou*/
printf("File Saved as Output.txt");
}
int main(void)
{
PASSENGERS passenger[53];
readfile(passenger);
do{
printf("\n\nNeo Sistima Katagrafis Thesewn Leoforeiou\n");
printf("Please make a selection:\n\n");
printf("0. Exit\n");
printf("1. Empty Seats \n");
printf("2. Book Specific Seat \n");
printf("3. Advanced Search of Booked Seats\n");
printf("4. Cancel Seat Booking\n");
printf("5. Show List of Booked Seats\n");
scanf(" %c",&selection);
if (selection=='1')
countfreeseats(passenger);
else if (selection=='2')
{
printf("Please give seat nr (between 1 and %d) that you want to book:\n", numberofseats);
scanf("%d",&temp);
if (temp >numberofseats || temp <= 0)
{printf("Error: Seat nr should be between 1 and %d", numberofseats);}
else if (strcmp(passenger[temp-1].fullname,"\0")!=0)
printf("Error: Seat is already booked");
else
changeData(&passenger[temp-1]);
}
else if (selection=='3')
{
char tempsel;
printf("Do you want to search with Name (1) or Phone Nr (2)?\n");
scanf(" %c",&tempsel);
searchpassenger(passenger,tempsel);
}
else if (selection=='4')
{
printf("Please give Seat Nr (between 1 and %d) that you want to Cancel Booking:\n", numberofseats);
scanf("%d",&temp);
if (temp >numberofseats || temp <= 0)
{printf("Error: Seat nr should be between 1 and %d", numberofseats);}
else if (strcmp(passenger[temp-1].fullname,"\0")==0)
printf("Error: Seat is already free");
else
cancelSeat(&passenger[temp-1]);
}
else if (selection=='5') /*Menu 6 - Emfanisi listas kratimenon thesewn taksinomimenon kata ayksonta arithmo*/
{
showList(passenger);
}
} while (selection!='0');
{
writeFile(passenger);
}
}
I'm starting coding this week so I'm dummy about it. I need help about return to main in my script. For example when I done Course registration part I can't return menu program is crashing
Codes:
#include <stdafx.h>
#include <stdio.h>
void eng();
void menu();
void huh();
int main()
{
menu();
return 0;
}
void menu()
{
int menu1choice;
printf("Menu\n");
printf("\n");
printf("1. Student Registration\n");
printf("2. Show Students.\n");
printf("Please enter number: ");
scanf_s("%d", &menu1choice);
switch (menu1choice)
{
case 1:
{
eng();
break;
}
}
}
void eng()
{
int a = 5;
char name[30];
printf("1.Student Number: ");
scanf_s("%d", &a);
//student number
printf("2.Name: ");
scanf_s("%s", &name);
//student name
getchar();
}
void huh()
{
int a = 5;
char name[30];
printf("Your Student number: %d\n", a);
printf("Your Name: %s\n", name);
//result
getchar();
}
Pls help me write return code lines, Thanks in Advance
Here is some code that may help you understand how to the mechanics of functions returning values, in your case back to the main function.
As for some advice, please read up about magic numbers and specifically why they are bad.
/*
* 35917794_main.c
*/
#include <stdio.h>
#define STU_REG 1
#define STU_SHOW 2
#define EXIT_SUCCESS 0
unsigned int show_menu(void);
unsigned int main
(
unsigned int argc,
unsigned char *arg[]
)
{
unsigned int menu1choice;
/*
* The next statements says run the function show_menu() and put the returned
* result in the variable menu1choice.
*/
menu1choice = show_menu();
switch(menu1choice)
{
case (STU_REG):
{
printf("\nGo do STUDENT REGISTRATION things...\n\n");
break;
}
case STU_SHOW:
{
printf("\nGo do SHOW STUDENT things...\n\n");
break;
}
default:
{
printf("\nGo do something for invalid option...\n\n");
break;
}
}
return(EXIT_SUCCESS);
}
unsigned int show_menu
(
void
)
{
unsigned int ui_W0;
printf("Menu\n\n");
printf("1. Student Registration\n");
printf("2. Show Students.\n");
printf("Please enter number: ");
scanf("%d", &ui_W0);
/*
* The next statements says run the function show_menu() has finished and returned
* returns the result in the variable ui_W0.
*/
return(ui_W0);
}
For my intro to programming class, we have to code a phonebook in C that lets users add contacts, as well as delete and display them. It also has to allocate and free memory as necessary (I tried to do this, but I honestly don't really know what I'm doing).
Anyway, I cannot figure out how to add a contact to the phonebook. I've pasted the relevant part of the program so far. It compiles, but it crashes every time I try to add a contact. Once I get this figured out, I think I can get the rest of the functions without too much trouble. If anyone could help me out, I'd really appreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct entry {
char fname[20];
char lname[20];
char pnumber[20];
} entry;
// function prototypes
void addentry(int, entry*, char addfname[20], char addlname[20], char addpnumber[20]);
main() {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20] = { '\0' };
char addlname[20] = { '\0' };
char addpnumber[20] = { '\0' };
entry *pcontacts;
pcontacts = (entry*)calloc(1, (sizeof(entry)));
if (pcontacts == NULL) {
printf("No memory is available.");
free(pcontacts);
return 0;
}
while (1) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts);
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
pnum++;
printf("\nEnter first name: ");
scanf("%s", addfname);
printf("Enter last name: ");
scanf("%s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%s", addpnumber);
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
break;
}
} while (inputtest == 1);
}
}
void addentry(int pnum, entry *pcontacts, char addfname[20], char addlname[20], char pnumber[20]) {
pcontacts = (entry*)malloc(pnum * (sizeof(entry)));
if (pcontacts != NULL) {
strcpy(*pcontacts[pnum - 1].fname, addfname);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}
You get strings from standard input with scanf, but you should tell scanf the maximum number of bytes to store to the destination arrays to avoid buffer overruns:
scanf("%19s", addfname);
...
scanf("%19s", addlname);
...
scanf("%19s", addpnumber);
The way you call addentry is incorrect:
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
You actually try to read the byte just after the end of addfname, addlname and addpnumber. You should instead pass the arrays themselves, that will be passed to the function addentry as pointers to their first bytes:
addentry(pnum, pcontacts, addfname, addlname, addpnumber);
addentry should reallocate the array with realloc. It should be passed a pointer to the array pointer to it can update the pointer in main.
addentry does not copy the strings correctly: it only copies one, but with a syntax error.
Here is a corrected version:
void addentry(int, entry**, char addfname[20], char addlname[20], char addpnumber[20]);
int main(void) {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20];
char addlname[20];
char addpnumber[20];
entry *pcontacts = NULL;
for (;;) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts); /* OK for NULL */
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
printf("\nEnter first name: ");
scanf("%19s", addfname);
printf("Enter last name: ");
scanf("%19s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%19s", addpnumber);
addentry(pnum, &pcontacts, addfname, addlname, addpnumber);
pnum++;
break;
}
} while (inputtest == 1);
}
}
/* add an entry at position pnum */
void addentry(int pnum, entry **pp, char addfname[20], char addlname[20], char pnumber[20]) {
entry *pcontact = *pp;
pcontacts = realloc(pcontacts, (pnum + 1) * sizeof(entry));
if (pcontacts != NULL) {
*pp = pcontacts; /* update pointer in main */
strcpy(pcontacts[pnum].fname, addfname);
strcpy(pcontacts[pnum].lname, addlname);
strcpy(pcontacts[pnum].pnumber, addpnumber);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}