The 1. and 3. menu items are working, but if I choose the 2. menu item it's not listing my data. Why is that?
(It has to be compiled and run in linux command line [NO IDE!])
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
struct log{
int id;
char name[20];
char location[20];
int quantity;
char quantity_type[10];
time_t added;
};
char fname[] = "data2.dat";
void add();
void listAll();
int nextId();
int main(){
int ch;
while(1){
system("clear");
printf("///Log stuff!///\n\n");
printf("1. Add\n");
printf("2. List all\n");
printf("0. Exit\n");
printf("\n///////////////////////////////\n\n");
printf("Choose a number from the menu: ");
scanf("%d", &ch);
switch(ch){
case 1: add();
break;
case 2: listAll();
break;
case 0: exit(0);
break;
}
}
return 0;
}
void add(){
FILE *f;
struct log log;
f = fopen(fname, "ab");
if(f == NULL){perror("Can't open!\n");}
log.id = nextId();
printf("\nName: ");
scanf("%s", log.name);
printf("\nLocation: ");
scanf("%s", log.location);
printf("\nQuantity: ");
scanf("%d", &log.quantity);
printf("\nQuantity type: ");
scanf("%s", log.quantity_type);
log.added = time(NULL);
fwrite(&log,sizeof(log),1,f);
fclose(f);
}
void listAll(){
FILE *f;
struct log log;
f = fopen(fname,"rb");
if(f == NULL){perror("Can't open!\n");exit(1);}
printf("\n///////////////////////////////\n\n");
printf("\tList of all data\n\n");
printf("///////////////////////////////\n\n");
while(fread(&log,sizeof(log),1,f) == 1){
printf("%d\t",log.id);
printf("%s\t",log.name);
printf("%s\t",log.location);
printf("%d\t",log.quantity);
printf("%s\t",log.quantity_type);
printf("%s",ctime(&log.added));
}
printf("\n///////////////////////////////\n\n");
fclose(f);
}
int nextId(){
FILE *f;
struct log log;
int id = 1;
f = fopen(fname, "rb");
if(f == NULL){perror("Can't open!\n");}
while(!feof(f)){
fread(&log, sizeof(log), 1, f);
if(log.id >= id){id = log.id + 1;}
}
fclose(f);
return id;
}
Is there a more elegant way to do this task?
This menu display/input choice/switch section of the code has a logic error
the screen is being cleared before the user has a chance to look at any displayed data.
Proper placement of calls to system(clear) and getchar() will fix the problem
a function should only have 1 normal exit. Any other exit points should be only for error conditions
You might try the following:
system(clear);
int done = 0;
while( !done )
{
printf("///Log stuff!///\n\n");
printf("1. Add\n");
printf("2. List all\n");
printf("3. Exit\n");
printf("\n///////////////////////////////\n\n");
printf("Choose a number from the menu: ");
if( 1 != scanf("%d", &ch) )
{ // then scanf failed
perror( "scanf for menu choice failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// eliminate menu from screen
system(clear);
switch(ch)
{
case 1:
add();
break;
case 2:
listAll();
printf( "\npress any key to continue\n" );
getchar();
break;
case 3:
done=1;
break;
default:
printf("\nyou entered an invalid menu selection, try again\n");
break;
} // end switch
} // end while
Related
The following code shows that there is an undefined reference to 'ext'. I'm not very adept in C. I really need a solution. This issue is present at line 37. Then there are 2 related errors at line 80. One is the one I previously mentioned and the other: "error:1d returned 1 exit status." I keep trying and getting this very same thing. I ask if someone can please kindly assist?
First problem:
if (fptr == NULL)
{
printf("Can't find file! Attempting to create file... \n");
fptr = fopen("ems.txt","w+");
if(fptr == NULL)
{
printf("Can't create file. Exiting...");
ext(1);
}
}
Second problem:
case 5:
puts("Exit was chosen");
ext(1);
break;
Structure here:
struct employee
{
char name[50];
char sex;
char adrs[50];
char dsgn[25];
int age,empID;
float slry;
};
Entire code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <stdbool.h>
#include <windows.h>
#include "struct.h"
void insert();
void list();
void edit();
void del();
void ext();
FILE * fptr, *ftemp;
struct employee e;
long int recsize;
char empname[50];
int main()
{
int choice;
fptr = fopen("ems.txt", "r+");
if (fptr == NULL)
{
printf("Can't find file! Attempting to create file... \n");
fptr = fopen("ems.txt","w+");
if(fptr == NULL)
{
printf("Can't create file. Exiting...");
ext(1);
}
}
//Explain the reason for this?
//recsize = (long int) sizeof(e);//
while(1)
{
printf("*******************************\n");
printf("\nEmployee management system");
printf("\n1. Insert employee information");
printf("\n2. List all employee information");
printf("\n3. Edit employee information");
printf("\n4. Delete employee information");
printf("\n5. Exit");
printf("\n\n*****************************\n");
printf("\n\n Enter your choice: ");
scanf("%d", &choice);
fflush(stdin);
switch(choice)
{
case 1:
puts("Insert was chosen");
insert();
break;
case 2:
puts("List was chosen");
list();
break;
case 3:
puts("Edit was chosen");
edit();
break;
case 4:
puts("Delete was chosen");
del();
break;
case 5:
puts("Exit was chosen");
ext(1);
break;
default:
puts("Choice is incorrect!!");
continue;
}
}
return 0;
}
void insert()
{
char next;
do
{
printf("********************************************************** \n");
printf("\nEnter the name of the employee: ");
fgets(e.name, sizeof(e.name), stdin);
printf("\nEnter the sex of the employee (M/m or F/f): ");
fgets(&e.sex, sizeof(e.sex), stdin);
printf("\nEnter the address of the employee: ");
fgets(e.adrs, sizeof(e.adrs), stdin);
printf("\nEnter designation of the employee: ");
fgets(e.dsgn, sizeof(e.dsgn), stdin);
printf("\nEnter age of the employee: ");
scanf("%d", &e.age);
printf("\nEnter basic salary of the employee: ");
scanf("%f", &e.slry);
printf("\nEnter the employee's ID: ");
scanf("%d", &e.empID);
fputs(e.name, fptr);
fputs(&e.sex, fptr);
fputs(e.adrs, fptr);
fputs(e.dsgn, fptr);
fprintf(fptr, "%d \n%f \n%d \n", e.age, e.slry, e.empID);
// fwrite(&e,recsize,1,fptr);
fflush(stdin);
printf("\nDo you want to input more? (y/n): ");
next = getche();
printf("\n");
}
while(next !='n');
fclose(fptr);
}
void list ()
{
/* what is going on here??? */
while(fread(&e,recsize,1,fptr)==1)
{
printf("\n%s %c %s %s %d %.2f %d",e.name,e.sex,e.adrs,e.dsgn,e.age,e.slry,e.empID);
}
getche();
return ;
}
void edit ()
{
char next;
do
{
printf("Enter the employee name to be edited: ");
scanf("%s", empname);
while(fread(&e,recsize,1,fptr)==1)
{
if(strcmp(e.name,empname) == 0)
{
printf("\nEnter new name,sex,address,designation,age,salary,employee ID ");
scanf("%s %c %s %s %d %f %d",e.name,&e.sex,e.adrs,e.dsgn,&e.age,&e.slry,&e.empID);
fseek(fptr,-recsize,SEEK_CUR);
fwrite(&e,recsize,1,fptr);
break;
}
}
printf("\nEdit another record(y/n)");
next = getche();
fflush(stdin);
}
while(next != 'n');
return ;
}
void del()
{
char next;
do
{
printf("\nEnter name of employee to delete: ");
scanf("%s",empname);
ftemp = fopen("Temp.dat","wb");
while(fread(&e,recsize,1,fptr) == 1)
{
if(strcmp(e.name,empname) != 0)
{
fwrite(&e,recsize,1,ftemp);
}
}
fclose(fptr);
fclose(ftemp);
remove("ems.txt");
rename("Temp.dat","ems.txt");
fptr = fopen("ems.txt", "rb+");
printf("Delete another record(y/n)");
fflush(stdin);
next = getche();
}while(next !='n');
}
Are you sure you've posted an [mcve]? You declare void ext();, which is equivalent to void ext(int), which is how you should have declared it, because the old empty () form predates the standards (it's ancient) and causes no end of confusions. So you've declared it, but you have not defined it anywhere. If it were extern void ext(int), then you would not get the compiler error, but you would probably get a linker error, as you haven't written the ext function and the linker won't be able to find it.
If you really intended to use the stdlib function exit, then you should remove the void ext() declaration and recompile.
Update related to additional comments entered while I was distractedly entering the above:
This is just an FYI. You can create aliases for function names, using preprocessor macros:
#define ext(errorCode) exit(errorCode)
Im basically Writing a program that creates, reads, updates and
deletes records in a binary file.
Everything compiles correctly, no syntax errors, but I do have some
bugs.
KNOWN BUGS
1.) Imputing any strings does not work, using fgets
2.) Ctrl-D Does Work but outputs a 'default' error before it exits.
3.) Update does not work (Not my main issue at the moment as the others are more important for now.)
4?) I'm not sure if the menu is working how it's supposed to work. I
think the do while is correct, since in the menu if I select and hit
CTRL-D it does exit the program. Just wanna be sure.
Right now I just want to know why, It is skipping the courseName in
the inputs function.
Here is my code thus far
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
typedef struct{
char courseName [64];
char courseSched [4];
unsigned int courseHours;
unsigned int courseSize;} COURSE;
FILE *pfileCourse;
int courseNumber = 0;
//Prototypes
void inputDetails(COURSE *c);
void readCourseRecord();
void createCourseRecord();
void print_menu();
void modifyCourseInfo();
void deleteCourse();
void display(COURSE c);
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char *argv[]) {
char choice; // this is the choice
printf("Enter one of the following actions or press CTRL-D to exit\n");
printf("C - Create a new course record\n");
printf("R - Read an existing course record\n");
printf("U - Update an existing course record\n");
printf("D - Delete an existing course record\n");
do{
choice = getchar();
switch(choice) {
case 'c':
case 'C':
printf("YOU PICKED C for Create\n");
createCourseRecord();
break;
case 'r':
case 'R':
printf("This is Choice R\n");
readCourseRecord();
break;
case 'u':
case 'U':
printf("Here is where you update an existing course\n");
modifyCourseInfo();
break;
case 'd':
case 'D':
printf("here is where you Delete an existing course record\n");
deleteCourse();
break;
default:
printf("Wrong Choice!\n");
}
}while(choice != EOF);
return 0;
}
void createCourseRecord() {
COURSE data;
pfileCourse = fopen("courses.dat", "ab");
printf("Please Enter The Details of The Course\n");
inputDetails(&data);
fwrite(&data, sizeof(data), 1, pfileCourse);
fclose(pfileCourse);
printf("Course Has Been Created!\n");
}
void inputDetails(COURSE *c) {
printf("Enter a course number: \n");
scanf("%d", &courseNumber);
printf("Enter a Course Name: \n");
fgets(c->courseName, sizeof(courseName), stdin);
printf("Enter the course schedule (MWF or TR): \n");
fgets(c->courseSched, 4, stdin);
fflush(stdin);
printf("Enter the course credit hours: \n");
scanf("%d",&c->courseHours);
fflush(stdin);
printf("Enter Number of Students Enrolled: \n");
scanf("%d",&c->courseSize);
return;
}
void readCourseRecord(){
COURSE data;
int flag = 0;
int readCourseNumber = 0;
printf("Please Enter a Course Number to Display\n");
scanf("%d", &readCourseNumber);
fflush(stdin);
pfileCourse = fopen("courses.dat", "rb");
while((fread(&data, sizeof(data), 1, pfileCourse)) > 0) {
if(readCourseNumber == courseNumber)
{
display(data);
flag = 1;
}
}
fclose(pfileCourse);
if(flag == 0)
printf("Course not Found!\n");
}
void deleteCourse(){
int newCourseNum;
COURSE data;
FILE *file2;
printf("Please Enter The Course You Wish You Delete\n");
scanf("%d", &newCourseNum);
pfileCourse = fopen("courses.dat", "rb");
file2 = fopen("temp.dat", "wb");
rewind(pfileCourse);
while((fread(&data, sizeof(data), 1, pfileCourse)) > 0)
{
if(courseNumber != newCourseNum)
{
fwrite(&data, sizeof(data), 1, file2);
}
}
fclose(file2);
fclose(pfileCourse);
remove("courses.dat");
rename("temp.dat", "courses.dat");
printf("%d was Successfully deleted\n", newCourseNum);
}
void modifyCourseInfo()
{
COURSE data;
int newCourseNum, found = 0;
printf("Modify\n");
printf("Please Enter The Course You Wish You Modify\n");
scanf("%d", &newCourseNum);
pfileCourse = fopen("courses.dat", "rb+");
while ((fread(&data, sizeof(data), 1, pfileCourse)) > 0 && found == 0)
{
if (courseNumber == newCourseNum)
{
display(data);
printf("Please Enter New Details\n");
inputDetails(&data);
fseek(pfileCourse, - (long)sizeof(data), 1);
fwrite(&data, sizeof(data), 1, pfileCourse);
printf("Course Updated\n");
found == 1;
}
}
fclose(pfileCourse);
if(found == 0)
printf("ERROR: course not found\n");
}
void display(COURSE c){
printf("courseNumber:\t %d\n", courseNumber);
printf("courseName:\t %s\n",c.courseName);
printf("courseSched:\t %s\n",c.courseSched);
printf("courseName:\t %d\n",c.courseHours);
printf("courseSize:\t %d\n",c.courseSize);
}
It doesn't skip courseName, courseName just gets value '\n' because scanf function stops reading your input BEFORE white space. Scanf ignores any whitespace characters encountered before the next non-whitespace character. So you can just add
scanf("%d[^\n]", &courseNumber);
getchar();
after every scanf you have but I'd recommend you to use fgets function for every interactive input.
while i'm working on my manii project phonebook , i faced some problems in delete function when there are multi result for the same first name (i use first name to search about the contact that i want to delete)
in this case i made extra variable in my structure called "ID" and this ID Auto fill in my program (so each user has a unique id) , so i can later find exactly the result that the user want to delete it ,and it works fine , but when i delete a contact from the file it left me with a gap and this effect on the next contact
For Example :
i have 3 contacts each one has an iD 1 , 2 and 3 , when i delete No.2 , it become 1 and 3 , when i add a new user my Auto fill loop will count the number of the contacts (2) and give the new one ID of 3 , that left me with 3 contacts with ID of 1 , 3 , and 3 and this's wrong
so i came with an idea to Reset all the IDs after each Delete operation , it seems good for me and this few line should do it , i don't know why this part doesn't work , even i tried to put this loop in add() function so it should be good at this position too , but it doesn't work too
// reset all ids
rewind(ft);
int id=1;
while(fread(&p,sizeof(p),1,ft)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,ft);
id++;
}
This is my Full code with 0 Errors and 0 warning , and it work fine except the part of reset ids
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <conio.h>
struct address // nested
{
char city[30],
street[30];
int flat;
};
struct phonebook // main
{
int id;
char firstName[20],
lastName[20];
struct address add;
long int phNumber;
char email[50];
};
// functions ...
void launcher();
void menu();
void add();
void load();
void query();
void Delete();
void modify();
void back();
void scan(char *name);
int main()
{
system("color 1e");
printf("Let's start!\n");
launcher();
return 0;
}
void launcher()
{
menu();
}
void back()
{
menu();
}
void menu()
{
system("cls");
printf("\t\t *********** PhoneBook! *************");
printf("\n\n\t\t\t\t <| Menu |>\t\t\n\n");
printf("\t\t1.Add \t2.Load \t3.Query \n\t\t4.Modify \t5.Delete\t6.Exit\n");
switch(getch())
{
case '1' :
add();
break;
case '2' :
load();
break;
case '3' :
query();
break;
case '4' :
modify();
break;
case '5' :
Delete();
break;
case '6' :
printf("the program exit successfully");
exit(0);
break;
default:
system("cls");
int i;
for(i=15 ; i>-1 ; i--)
{
system("cls");
printf("\nInvalid key Entered , please enter any key from 1 to 6 only!\n");
printf("you will back to the main menu automatically in %d seconds",i);
Sleep(1000);
}
menu();
}
}
void add()
{
system("cls");
struct phonebook p; // local define
FILE *f;
f= fopen("data","ab+");
int id=1;
while(fread(&p,sizeof(p),1,f)==1)
{
id++;
}
printf("\nFirst Name : ");
scan(p.firstName);
printf("\nLast Name : ");
scan(p.lastName);
printf("\nEnter the address .. ");
printf("\n\tCity : ");
scan(p.add.city);
printf("\n\tStreet : ");
scan(p.add.street);
printf("\n\tFlat : ");
scanf(" %d",&p.add.flat);
printf("\nPhone number : ");
scanf(" %ld",&p.phNumber);
printf("\nEmail : ");
scan(p.email);
p.id=id; // Auto fill
fwrite(&p,sizeof(p),1,f); // saving the data into a file
fclose(f);
puts("\n\n\t\tdata is saved successfully!");
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void load()
{
struct phonebook p;
system("cls");
FILE* f;
f = fopen("data","rb");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
while(fread(&p,sizeof(p),1,f)==1)
{
printf("\n\n\t\t\t\t <| loading List |>\t\t\n\n");
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\nid : %d\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email,p.id);
puts("\t\t * Enter any key to show more *");
getch();
system("cls");
}
fclose(f);
puts("\t\tno more data to show !");
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void query()
{
system("cls");
struct phonebook p;
FILE* f;
f = fopen("data","rb");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
char name[50];
int flag=0;
printf("please enter a name : ");
scan(name);
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
flag++;
printf("\n[%d] result found\n",flag); // ==> static text
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
puts("");
}
}
if(flag == 0)
{
puts("file not found");
}
fclose(f);
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
void modify()
{
system("cls");
struct phonebook p,s;
FILE* f;
f = fopen("data","rb+");
if(f==NULL)
{
puts("\n An error occur while opening the file >");
exit(1);
}
char name[50];
int flag=0;
printf("please enter a name : ");
scan(name);
system("cls");
int results[50];
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
results[flag] = p.id;
flag++;
printf("\n\n >> full information about the result No. [%d] :- \n",p.id);
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
}
}
if(flag == 0)
{
puts("file not found");
}
else
{
int choice,i,found=0;
int lastResultID = p.id;
puts("Please enter the Number of the result to confirm your order");
scanf(" %d",&choice);
// confirmation
for(i=0 ; i<flag ;i++){
if(results[i] == choice){
found =1;
break;
}
}
if(found == 0){
puts("\n Ops! Result not found.\nmaybe you entered a wrong No. OR an Error occurs Try again.");
Sleep(5000);
back();
}else{
//printf("\n%d\n",lastResultID);
puts("\n >> Are you want to modify this result ? type (Y) for Yes or (N) for No !");
char c = getch();
if( c == 'Y' || c == 'y')
{
system("cls");
printf("\nFirst Name : ");
scan(s.firstName);
printf("\nLast Name : ");
scan(s.lastName);
printf("\nEnter the address .. ");
printf("\n\tCity : ");
scan(s.add.city);
printf("\n\tStreet : ");
scan(s.add.street);
printf("\n\tFlat : ");
scanf(" %d",&s.add.flat);
printf("\nPhone number : ");
scanf(" %ld",&s.phNumber);
printf("\nEmail : ");
scan(s.email);
fseek(f,-sizeof(p)*(lastResultID-choice+1),SEEK_CUR);
s.id=choice;
fwrite(&s,sizeof(p),1,f); // saving
puts("\n\t\tyour data is modified!");
fclose(f);
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing change ! , press any key to back to the main menu !");
getch();
back();
}
}
}
}
void Delete()
{
int found =0;
system("cls");
struct phonebook p,s;
FILE* f;
FILE* ft;
f = fopen("data","rb");
ft = fopen("temp","ab+");
if(f == NULL || ft == NULL)
{
puts("\n An error occur while opening the file >");
perror("fopen() failed");
exit(1);
}
char name[50];
int flag=0,i;
int results[50];
printf("please enter a name : ");
scan(name);
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)==0)
{
results[flag] = p.id;
flag++;
printf("\n\n >> full information about the result No. [%d] :- \n",p.id);
printf("First name : %s\nLast name : %s\nAddress Info ...\nCity : %s\nStreet : %s\nFlat : %d\nPhone Number : %ld\nEmail : %s\n",p.firstName,p.lastName,p.add.city,p.add.street,p.add.flat,p.phNumber,p.email);
}
}
if(flag == 0)
{
puts("file not found");
}
else{
puts(" ");
int choice,check=0;
puts("please enter the number of the result which you want to delete");
scanf(" %d",&choice);
// confirmation
for(i=0 ; i<flag ;i++){
if(results[i] == choice){
check =1;
break;
}
}
if(check == 0){
puts("\n Oops! Result not found.\nmaybe you entered a wrong No. OR an Error occurred Try again later.");
Sleep(3500);
back();
}else{
puts("\n >> Do you want to delete this result ? type (Y) for Yes or (N) for No !");
char c = getch();
rewind(f); // reset the pointer
if( c == 'Y' || c == 'y')
{
system("cls");
while(fread(&p,sizeof(p),1,f)==1)
{
if(choice != p.id)
fwrite(&p,sizeof(p),1,ft);
if(choice == p.id)
found++;
}
//perror("fread() failed");
if(found == 0)
{
puts("An error occurred , please try again");
remove("temp");
Sleep(3500);
back();
fclose(f); // ==?
fclose(ft); // ==?
}
else
{
// reset all ids
rewind(ft);
int id=1;
while(fread(&p,sizeof(p),1,ft)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,ft);
id++;
}
fclose(f); // ==?
fclose(ft); // ==?
remove("data");
int c = rename("temp","data");
puts("file is deleted successfully");
if(c != 0)
perror("rename() failed"); // handling for rename error
}
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing changed ! , press any key to back to the main menu !");
getch();
back();
}
}
}
/*else
{
puts("\n >> Are you want to delete this result ? type (Y) for Yes or (N) for No !");
char c = getch();
if( c == 'Y' || c == 'y')
{
rewind(f);
while(fread(&p,sizeof(p),1,f)==1)
{
if(strcmp(name,p.firstName)!=0)
fwrite(&p,sizeof(p),1,ft);
}
fclose(f);
fclose(ft);
remove("data");
int c = rename("temp","data");
puts("file is deleted successfully");
if(c != 0)
perror("rename() failed");
// reset all ids
int id=1;
while(fread(&p,sizeof(p),1,f)==1)
{
p.id = id;
fwrite(&p,sizeof(p),1,f);
id++;
}
puts("\t\tEnter any key to back to the main menu");
getch();
back();
}
else
{
system("cls");
puts("nothing change ! , press any key to back to the main menu !");
getch();
back();
}
}*/
}
void scan(char *name)
{
int i=0,j;
char c,ch;
do
{
c=getch();
if(c!=8&&c!=13)
{
*(name+i)=c;
putch(c);
i++;
}
if(c==8)
{
if(i>0)
{
i--;
}
// printf("h");
system("cls");
for(j=0; j<i; j++)
{
ch=*(name+j);
putch(ch);
}
}
}
while(c!=13);
*(name+i)='\0';
}
Thanks in advance
What about using the highest id+1 instead of counting them?
int id = 1;
while(fread(&p,sizeof(p),1,f)==1)
{
if (p.id >= id) id = p.id+1;
}
You cannot interleave fread and fwrite without an intervening fseek:
7.21.5.3/7 When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function or to a file positioning function (fseek, fsetpos, or rewind), and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.
I'm kind of new to programming C with Code::Blocks(Version 12.11), started this semester in my college, but I manage.
I recently learned in class about pointers, memory allocation and dynamic arrays(none are my forte), and I incorporated them in my program(and it compiles)
Now the problem comes when I run the Program and go to Menu -> Add a Product, the program terminâtes when I input a price and I receive "Process Returned -1073741819 (0xc0000005)".
I did some research and found out it's an access violation but I don't really understand how to correct it.
Regards
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxCharName 64
#define maxCharUserPass 8
#define maxCharId 5
// Product Structure
typedef struct{
char name[maxCharName];
char idCode[maxCharId];
float price;
float stock;
}product;
// DataBase of Products
typedef struct{
int sizeT;
product *array;
} TProducts;
TProducts a;
// Press any Key on the Keyboard to Proceed
void pressKeyToContinue(){
puts("\n\n\n Please Press any Key to Continue...");
getchar();
}
// Start Page
void startPage(){
puts("\n\n\n -- Welcome to WeePro Manager --\n\n");
puts(" -- Version 1.0 --\n\n\n\n");
puts(" -- Developped By: Nick --");
pressKeyToContinue();
system("cls");
}
// Program Terminator
void shutdown(){
puts("\n\n\n Good-Bye");
pressKeyToContinue(); // Awaits User Input
exit(0);
}
// Asks User Information for Verification
int userLogin(){
char userName[maxCharUserPass] = "WPuser";
char inputUserName[maxCharUserPass];
char passWord[maxCharUserPass] = "12345";
char inputPassWord[maxCharUserPass];
printf("Username? ");
scanf("%s",inputUserName); fflush(stdin);
printf("Password? ");
scanf("%s", inputPassWord); fflush(stdin);
system("cls");
if((strcmp(userName, inputUserName) == 0)&&(strcmp(passWord, inputPassWord) == 0)){
return 1;
}else{ return 0;}
}
// Lists All Products With their Respective Information
void listAll(){
int idx = 0;
puts("List:");
while((idx < a.sizeT)&&(a.array[idx].name != NULL)){
printf(":::%s ( id: %s )", a.array[idx].name, a.array[idx].idCode);
printf("Price: %6.2f eur/g", a.array[idx].price);
printf("Stock: %6.2f g", a.array[idx].stock);
idx++;
}
pressKeyToContinue();
system("cls");
}
// Input Product ID Code
char* inputIdCode(){
char* tempIdCode;
puts("ID Code?");
scanf("%s", tempIdCode);
system("cls");
return tempIdCode;
}
// Search By ID Code
int searchIdCode(){
int idx = 0;
char* tempIdCode;
tempIdCode = inputIdCode();
do{
if(strcmp(a.array[idx].idCode, tempIdCode) == 0){
return idx;
}else{
idx++;
}
}while(idx < a.sizeT);
puts("No Product With Such an ID Code!");
return -1;
}
// Input Product Name
char *inputProductName(int length){
char name[maxCharName];
puts("Product Name?");
scanf("%s", name); fflush(stdin);
system("cls");
return name;
}
// Input Product Price
float inputProductPrice(int length){
float price;
puts("Product Price?");
scanf("%f", price); fflush(stdin);
system("cls");
return price;
}
// Input Product Stock
float inputProductQuantity(int length){
float quantity;
puts("Product Stock?");
scanf("%f", quantity); fflush(stdin);
system("cls");
return quantity;
}
/////////////////
// Add Product //
/////////////////
// New Product Adder
void addProduct(){
char* tempStr;
float temp;
if(a.sizeT == 0){
a.sizeT = 1;
a.array = (product*)malloc((a.sizeT)*sizeof(product));
}else{
a.sizeT++;
a.array = (product*)realloc(a.array, (a.sizeT)*sizeof(product));
}
tempStr = inputProductName(a.sizeT);
strcpy(a.array[a.sizeT].name, tempStr);
temp = inputProductPrice(a.sizeT);
temp = inputProductQuantity(a.sizeT);
system("cls");
}
void transaction(){}
////////////////////
// Delete Product //
////////////////////
// Delete Product
void deleteProduct(){
int idx, idxPro;
char* tempIdCode;
puts("Delete Which Product?\n");
tempIdCode = inputIdCode();
idxPro = searchIdCode(tempIdCode);
idx = idxPro + 1;
while(idx < a.sizeT){
a.array[idx] = a.array[idx+1];
idx++;
}
a.array = realloc(a.array, (a.sizeT-1)*sizeof(product));
}
//Product Information Modifier
void modifyProduct(){
char choice;
int tabLength;
do{
puts("Modify What?\n");
puts(" -> [N]ame\n");
puts(" -> [P]rice\n");
puts(" -> [S]tock\n\n");
puts(" -> [R]eturn to Previous Menu"); // Prints the Menus' Options
scanf("%c", &choice);
choice = toupper(choice); // Save Users' Choice And Up Case
fflush(stdin);
switch(choice){
case 'N':
system("cls");
tabLength = searchIdCode();
inputProductName(tabLength);
break;
case 'P':
system("cls");
tabLength = searchIdCode();
inputProductPrice(tabLength);
break;
case 'S':
system("cls");
tabLength = searchIdCode();
inputProductQuantity(tabLength);
break;
case 'R':
system("cls");
returnToMenu2();
break;
default:
puts("Something Went Wrong!\n");
pressKeyToContinue();
system("cls");
}
}while(choice != 'o');
}
// Sub-Menu Interface
void menu(){
char choice;
do{
puts("Please Make Your Selection.\n");
puts(" -> [A]dd a New Product\n");
puts(" -> [M]odify a Product\n");
puts(" -> [D]elete a Product\n\n");
puts(" -> [R]eturn to Main Menu"); // Prints the Menus' Options
scanf("%c", &choice); fflush(stdin);
choice = toupper(choice); // Save Users' Choice And Up Case
switch(choice){
case 'A':
system("cls");
addProduct();
break;
case 'M':
system("cls");
modifyProduct();
break;
case 'D':
system("cls");
deleteProduct();
break;
case 'R':
system("cls");
returnToMenu1();
break;
default:
puts("Something Went Wrong!\n");
pressKeyToContinue();
system("cls");
}
}while(choice != 'o');
}
// Return To Ma
> Blockquote
in Menu
void returnToMenu2(){
menu();
}
// Main Menu
void controlPanel(){
char choice;
do{
puts("Please Make Your Selection.\n");
puts(" -> [T]ransaction\n");
puts(" -> [M]enu\n");
puts(" -> [L]ist\n");
puts(" -> [S]hutdown"); // Prints the Panels' Options
scanf("%c", &choice); fflush(stdin);
choice = toupper(choice); // Save Users' Choice And Up Case
switch(choice){
case 'T':
system("cls");
transaction();
break;
case 'M':
system("cls");
menu();
break;
case 'L':
system("cls");
listAll();
break;
case 'S':
system("cls");
shutdown();
break;
default:
puts("Something Went Wrong!\n");
pressKeyToContinue();
system("cls");
}
}while(choice != 'o');
}
// Return To Main Menu
void returnToMenu1(){
controlPanel();
}
int main(){
int loginSuccess=1;
//loginSuccess = userLogin();
switch(loginSuccess){
case 0:
shutdown();
break;
case 1:
startPage();
controlPanel();
break;
}
}
An attempt is being made to write to randon memory, via the uninitialized pointer tempIdCode:
char* inputIdCode(){
char* tempIdCode;
puts("ID Code?");
scanf("%s", tempIdCode);
system("cls");
return tempIdCode;
}
You need to allocate memory for tempIdCode before attempting to write to it. You must use malloc() here (and not return the address of a local array):
char* tempIdCode = malloc(20);
if (tempIdCode)
{
/* The format specifier "%19s" instructs scanf()
to read at most 19 characters, one less than
allocated to allow for terminating null character
written by scanf(), to prevent potential buffer
overrun. */
scanf("%19s", tempIdCode);
}
The caller of the function must explicitly check for a return NULL pointer. The caller must also free() the allocated memory.
This is a killer:
// Input Product Name
char *inputProductName(int length){
char name[maxCharName];
puts("Product Name?");
scanf("%s", name); fflush(stdin);
system("cls");
return name;
}
The reference returned by this function points to an already freed block of memory on the stack, as char name is only valid as long the program is inside the function name is declared in.
When leaving the function name is freed automagically, so any dereferencing of the function's result leads to UB, as it most propably will be accessing unallocated memory.
To solve this you might like to pass in a buffer, where to read the data into:
// Input Product Name
char * inputProductName(int length, char * name){
puts("Product Name?");
scanf("%s", name); fflush(stdin);
system("cls");
return name;
}
and call it like this:
// New Product Adder
void addProduct(){
char* tempStr;
float temp;
if(a.sizeT == 0){
a.array = malloc((a.sizeT)*sizeof(product));
}else{
a.array = realloc(a.array, (a.sizeT)*sizeof(product));
}
a.sizeT++;
inputProductName(a.sizeT, a.array[a.sizeT].name);
...
#include <stdio.h>
#include <stdlib.h> //for the clear screen function
#include <string.h>
struct customer
{
int custID;
char custName[50];
char custAddress[100];
};
typedef struct customer c;
void load_menu(void);
void customers_menu(void);
void createNew(void); //initialize your file
void add_Customer(c c1[30]); //add a new record to the file
FILE *fp;
int main(void)
{
load_menu();
return 0;
}
void load_menu(void)
{
int choice;
do
{
printf("Customer Orders Main Menu. \n\n");
printf("Please enter your choice: \n");
printf("1. Customer's Menu \n");
printf("2. Orders Menu\n");
printf("3. Product Stock Menu\n");
printf("4. Exit\n");
printf("\n");
if (scanf("%d",&choice)==1)
{
switch(choice)
{
case 1: system ("cls");
customers_menu();
printf("\n");
break;
case 2: system ("cls");
orders_menu();
printf("\n");
break;
case 3: system ("cls");
stock_menu();
printf("\n");
break;
case 4: printf("Quitting program!\n");
break;
default: printf("Invalid choice! Please try again\n");
printf("\n");
break;
}
}
else
{
fflush(stdin);
printf("Characters are invalid, please enter a number: \n ");
choice=0;
}
}while((choice !=4));
}
void createNew(void)
{
FILE *fp;
fp=fopen("Customer.dat", "w");
if (fp==NULL)
printf("File creation failed! \n");
else
{
printf("File created! \n");
fclose(fp);
}
}
void add_Customer (c c1[30])
{
int i, n , cc=0;
FILE *fp;
fp=fopen("Customer.dat", "a");
system("cls");
if(fp==NULL)
{
printf("File Creation Failed!");
}
system("cls");
printf("Enter the number of Customers: ");
scanf("%d", &n);
for(i=0;i<n;i++)
{
printf("Customer's ID (numbers only) : ");
scanf("%d", &c1[i].custID);
printf("Customer's Name : ");
gets(c1[i].custName);
printf("Customer's Address : ");
gets(c1[i].custAddress);
fwrite(&c1[i], sizeof(c), 1, fp);
}cc++;
fclose(fp);
}
void recordCount(c c1[30], int *count)
{
add_Customer(c1);
count=0;
count++;
}
void customers_menu(void)
{
int choice;
c c1[30];
int i;
do
{
printf("\n");
printf("Customers Menu \n\n");
printf("Please enter your choice: \n");
printf("1. Add Customer \n");
printf("2.\n");
printf("3.\n");
printf("4. Go back to Main Menu \n");
recordCount (c1, &i);
if (scanf("%d",&choice)==1)
{
switch(choice)
{
case 1: add_Customer(c1);
createNew();
printf("\n");
break;
case 2:
printf("\n");
break;
case 3:
printf("\n");
break;
case 4: printf("Going back to Main Menu\n");
system ("cls");
break;
default: printf("Invalid choice! Please try again\n");
printf("\n");
break;
}
}
else
{
fflush(stdin);
printf("Characters are invalid, please enter a number: \n ");
choice=0;
}
}while((choice !=4));
I have a problem since when I enter the Customers Menu it is staring to execute case 1 immediately (which still doesn't work properly). Can someone help me fix this error please because I tried everything I know and it is still in vain
I think your issue is that in customers_menu() you output the menu, but do not read the selection, instead you call recordCount() which directly calls addCustomer().
After addCustomer() we return the customers_menu() which then calls scanf() for the long gone menu.
A few other notes:
gets() is not good, I suggest you use scanf() (with %s) instead.
Doing a printf() then clearing the screen is a bit pointless.
Error messages should really go to stderr (fprintf(stderr,...)) rather than stdout (printf(...))
You code is a missing trailing }.
cc is added to, but not used.
This problem coming from if (scanf("%d",&choice)==1) because scanf will not return choice. If you enter valid answer (like number), then it returns 1 and switch case work with 1. I think that's the problem.
If you enter char instead of integer, scanf will return 0.