dealing with files and structures in c - c

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.

Related

Removing nodes from middle of Linked List and infinite loop in C

I'm trying to create a linked list structure in C to allow a user to enter a list of direct debits with a description, then allow the user to select and delete any node. The solution I got from many sources, while researching, isn't working. No matter which node I choose, the latest one is always deleted.
Can anyone tell me where the problem in my code is?
It's also started throwing infinite loops of one node when printining the entire list
#define true 1
#define false 0
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct Banknode {
float debit;
char description[100];
struct Banknode *next;
}Banknode;
struct Banknode *latestPtr = NULL;
int isEmpty(void);
void add(float fig, char info[100]);
float rmv(int n);
void allList();
void showMenu();
int main()
{
latestPtr = NULL;
int choice;
float deb;
char info[100];
int n;
//MENU
printf("\nWelcome to your DirectDebit management system");
printf("\nPlease select an option:");
printf("\n1. View Latest DirectDebit");
printf("\n2. View all DirectDebits");
printf("\n3. Add a DirectDebit");
printf("\n4. Remove a DirectDebit");
printf("\n5. Show menu");
printf("\n6. Exit\n");
while(choice != 6)
{
scanf("\n%d", &choice);
switch(choice)
{
case 1:
{
if(!isEmpty())
{
printf("\nThe latest DirectDebit is: \n%.2f for %s,\n", latestPtr->debit, latestPtr->description);
showMenu();
}
else
{
printf("\nAll DirectDebits have been removed.\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 2:
{
if(!isEmpty())
allList();
else
{
printf("\nYou have no DirectDebits\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 3:
{
printf("\nWhat is the amont of new DirectDebit?\n");
scanf("\n%f", &deb);
printf("\nPlease give a brief, unique description of the new DirectDebit\n");
fgets(info, 100, stdin);
scanf("%[^\n]%*c", info);
printf("\n Your DirectDebit amount is : %.2f", deb);
printf("\n And the description is: %s", info);
add(deb, info);
printf("\n");
showMenu();
break;
}
case 4:
{
if(!isEmpty())
{
if(latestPtr->next != NULL)
{
printf("\nPlease enter the number of the DirectDebit you wish to remove, by counting from the bottom up:\n");
allList();
scanf("\n%d", &n);
printf("\nRemoving DirectDebit\n");
printf("\n%.2f is removed from the list",rmv(n));
}
else
{
printf("\nAll DirectDebits have now been removed.\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
latestPtr = NULL;
}
}
else
{
printf("\nYou have no DirectDebits\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 5:
{
showMenu();
break;
}
case 6:
printf("Thank you, Goodbye!\n");
exit(1);
break;
default:
printf("\nInvalid choice.\n");
showMenu();
break;
}
}
}
int isEmpty(void)
{
if(latestPtr == NULL)
return true;
else
return false;
}
void allList()
{
struct Banknode *scanPtr = NULL;
scanPtr = latestPtr;
printf("\nYour current DirectDebits are: \n");
while(scanPtr->next != NULL)
{
printf("%.2f for %s,\n",scanPtr->debit, scanPtr->description);
scanPtr = scanPtr->next;
}
printf("%.2f for %s,\n",scanPtr->debit, scanPtr->description);
}
void add(float fig, char info[100])
{
struct Banknode *newPtr = (struct Banknode*)malloc(sizeof(struct Banknode));
if (newPtr != NULL)
{
newPtr->debit = fig;
strcpy((newPtr->description), info);
newPtr->next = latestPtr;
latestPtr = newPtr;
}
else
{
printf("%.2f not inserted. No memory available.\n", fig);
}
free(newPtr);
}
float rmv(int n)
{
int len = 0, i;
struct Banknode *rmvPtr = latestPtr;
while (rmvPtr != NULL)
{
rmvPtr = rmvPtr->next;
len++;
}
if (len < n)
return -9999;
else
rmvPtr = latestPtr;
for (i = 1; i < len-n+1; i++)
rmvPtr = rmvPtr->next;
float j = latestPtr->debit;
latestPtr = latestPtr->next;
return j;
}
void showMenu()
{
printf("\nPlease select an option:");
printf("\n1. View Latest DirectDebit");
printf("\n2. View all DirectDebits");
printf("\n3. Add a DirectDebit");
printf("\n4. Remove a DirectDebit");
printf("\n5. Show menu");
printf("\n6. Exit\n");
}

making a program to add a list of names in 2d array actually I just made a part of it and I have a lot of errors

my code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char names[10][31];
int u=0;
char new[31];
int ctr=1;
int notInList=0;
int y=0;
int i=0;
char *p;
strcpy(names[0],"mahmoud");
while(1)
{
printf("\t\t§§§Menu items§§§\n");
printf("1==>enter a new name\n");
printf("2==>search for a name\n");
printf("3==>delete a name from the list\n");
printf("Note !!.. ((if you want to exit the program press(1)and then type ((exit))\n");
fflush(stdin);
scanf("%i",&u);
notInList=1;
if(u==1)
{
printf("please enter a name : ");
fflush(stdin);
gets(new);
_strlwr(new);
if(strcmp(new,"exit")==0)
{
printf("bye bye\n");
break;
}
else
{
notInList=1;
for(int i=0;i<=ctr;i++)
{
p=strstr(new,names[i]);
if(strcmp(new,names[i])==0)
{
printf("the name is already exist\n");
break;
}
else if (p)
{
printf("did you mean (( %s ))\n",names[i]);
printf("1==>yes\n");
printf("2==>no\n");
fflush(stdin);
scanf("%d",&y);
if(y==1)
{
printf("the name is already exist\n");
break;
}
else if(y==2)
{
notInList=0;
strcpy(new,names[ctr]);
ctr++;
break;
}
else printf("plz enter a number from the list");
}
else
{
notInList=0;
}
}
if(notInList==0)
{
strcpy(new,names[ctr]);
ctr++;
for(int i=0;i<ctr;i++);
{
printf("%d==>%s\n",i+1,names[i]);
}
}
// break;
}
}
return 0;
}
the first problem is: when I enter ( 1) and then add a name is similar to the first name it printf to me did you mean ( )//// without a name
the second is when I want to add a new name it doesn't please help me
notice that he program is not finished only the first choise

C - Function not executing?

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

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
}

Calling the function directly works but calling from another function fails

When I use the display_menu function to call read_txt_file() it doesn't work. I am unable to get the file contents to the stdout but when I use the read_txt_file() directly, it works. I can see the contents of the file in stdout. What is the problem with the display_menu?
#include <stdio.h>
typedef struct filename
{
int age;
char name[100];
}name_t;
name_t * fname=NULL;
void quit()
{
printf("\nPress enter to exit");
fflush(stdin);
getchar();
}
enter(char prompt[])
{
puts(prompt);
fflush(stdin);
getchar();
}
void read_txt_file()
{
char ch;
fname=(name_t *)malloc(sizeof(name_t));
FILE *fptr=NULL;
atexit(quit);
printf("Please enter the file name to read : ");
fflush(stdin);
scanf("%s",fname->name);
fptr=fopen(fname->name,"r");
if(fptr == NULL)
{
perror("Could not open the file ");
return;
}
printf("+++++++++++++++++++++++++++++++++++++++++++++++++");
printf("Contents of the file %s are : ",fname->name);
**while(ch != EOF)
{
ch=fgetc(fptr);
printf("%c",ch);
}**
enter("press enter");
fclose(fptr);
}
display_menu()
{
int choice;
while(1)
{
system("cls");
printf("\t\t1.read and display from a file\n \
\b2.quit\n");
scanf("%d",&choice);
switch(choice)
{
case 1 :
read_txt_file();
break;
case 2 :
exit(0);
default :
printf("please enter proper choice(1-3)\n Enter to continue");
fflush(stdin);
getchar();
}
}
}
int main()
{
/*
read_txt_file();
*/
**display_menu();**
return 0;
}
After the scanf("%d",&choice); call, the input will still have a '\n' (the one of the return you pressed to enter the choice). So the file name will be empty. You can add a getchar() after reading the choice (to remove the '\n').

Resources