hey guys, uhh ok remember the old addressbook problem? well i solved it :cheesy: ! but now my prof gave us the same assignment but we have to do it as linked lists.. and i dont know how to use linked lists quite well yet.. this is my original code without the linked lists.
/*includes*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//Structure containing all contact information fields
struct contact {
char firstname [40]; //first name field
char lastname [40]; //last name field
char address [100]; //address field
char postalcode [7]; //postal code field
char phone[11]; //phone number field
struct contact *nextPtr; //pointer to next contact
};
struct student *pFirst = NULL;
struct student *pLast = NULL;
/*Function Prototypes*/
int enterchoice (void);
int addnewcontact ();
int isvalidpostalcode (struct contact pPtr[]);
int isvalidphone (struct contact nPtr[]);
void flush_in ();
int filewrite ();
int displaydata ();
int loaddata ();
int finalsave ();
void formatphonenumber (struct contact *gPtr);
void formatpostalcode (struct contact *hPtr);
void wordcap (struct contact aPtr[]);
void search();
void ClearList(struct student *pF);
/*i defined globally as a counter*/
int i=1;
/* Main Module
Takes no input
goes to the enter choice menu
*/
int main (void){
int choice;
printf ("\n *** Personal Contact Book v1.0 *** \n");
enterchoice (); //go to the main menu
return 0; //return 0 indicating successful termination
}
//Choice Entering Module
//Takes integer as input
//according to users choice, it goes to 6 different modules
int enterchoice (void)
{
int choice;
printf ("1)Add New Contact.\n2)Display Current Contacts.\n3)Search for a contact.\n4)Save Contacts to File.\n5)Load Contacts from File.\n6)Exit.\n");
printf (">");
scanf ("%d", &choice);
switch (choice){ //starting switch case
case 1:
addnewcontact(); //go to the adding a new contact module to add a new contact
break;
case 2:
displaydata (); //go to the display contact module to display latest contact added
break;
case 3:
search(); //go to the contact search module to search for a saved contact
break;
case 4:
filewrite(); // go to the file saving module to save contacts inputted
break;
case 5:
loaddata(); //go to the loading module to load and print saved contacts
break;
case 6: finalsave();//go to the final save module to save whatever changes were made to the file
break;
default: printf ("\nInvalid choice\n");
enterchoice(); //if choice was invalid, inform user then re-display menu
break;
}
}
/*add new contact module
takes first name, last name,
address, postal code and phone
number as input, after reading is done,
goes back to main menu*/
int addnewcontact ()
{
struct contact * pNew = NULL;
char choice = 'y'; //defining local variables
int z, y;
pNew = (struct contact *) (malloc( sizeof( struct contact)));
FILE *outfile; //declaring file pointer
outfile = fopen ("contactlist.dat", "w"); //opening file
while (choice == 'y'){ //start of outer while loop
printf ("\nAdding new contact: \n");
printf ("First name: ");
scanf("%s",pNew->firstname); //reading first name
printf ("Last name: ");
scanf("%s",pNew->lastname); //reading last name
printf ("Address: ");
flush_in();
gets (pNew->address); //reading address
printf ("Postal code: ");
scanf("%s",pNew->postalcode); //reading postal code
z = isvalidpostalcode (pNew->postalcode); //going to isvalidpostalcode module to validate postal code
//start of inner while loop, checking if inputted postal code is correct (module would return 1 in that case)
while (z != 1){
printf ("Invalid postal code, please enter a correct one.\n");
printf ("Postal code: ");
scanf("%s",pNew->postalcode);
flush_in();
z = isvalidpostalcode (pNew->postalcode); //validate newly entered postal code
}
printf ("Phone number: ");
scanf("%s",pNew->phone); //reading phone number
flush_in();
y = isvalidphone (pNew->phone); //going to isvalidphone module to validate phone number
//start of third inner while loop, checking if inputted phone number is correct (module would return 1 in that case)
while (y != 1){
printf ("Invalid phone number, Please enter a 10-Digit phone number starting with the area code.\n");
printf ("Phone number: ");
scanf("%s",pNew->phone); //reading new phone number
flush_in();
y = isvalidphone (pNew->phone); //validate newly entered phone number
}
printf ("\nWould you like to enter a new contact? "); //see if user wants to enter another contact
scanf ("%c", &choice);
i++;//increment records counter
pNew->nextPtr = NULL;
if (pFirst == NULL)
pFirst = pNew;
if (pLast != NULL)
pLast->nextPtr = pNew;
pLast = pNew;
}
ClearList (pFirst);
enterchoice (); //go back to main menu
return 0; //return 0 to indicate successful termination
}
/*This module takes the inputted
postal code in the addnewcontact module
and validates it, returns 1 if
correct, or returns 0if incorrect*/
int isvalidpostalcode(struct contact pPtr[])
{
int length = (int)(strlen(pPtr)); //finding the length of the passed string
if (length == 6){ //if the length is 6 characters, check if the sequence is 'letter' 'number' 'letter' 'number' 'letter' 'number'
if (isalpha(pPtr[0]) && isdigit(pPtr[1]) && isalpha(pPtr[2]) && isdigit(pPtr[3]) && isalpha(pPtr[4]) && isdigit(pPtr[5]))
{
return 1; //return 1 is this is true
}
else{
return 0; //otherwise return 0
} //end of inner else statement
}
else {
return 0; //otherwise if the length exceeds or is less than 6 return 0
} //end of outer else statement
}
/*Validating phone number function,
takes passed phone number as input
returns 1 if its valid, and 0 if invalid*/
int isvalidphone (struct contact nPtr[])
{
int length = (int)(strlen(nPtr)); //finding length of string
if (length <= 10){ //if the length is less than or equal to 10 then check if sequence is 10 numbers
if (isdigit(nPtr[0]) && isdigit(nPtr[1]) && isdigit(nPtr[2]) && isdigit(nPtr[3]) && isdigit(nPtr[4]) && isdigit(nPtr[5]) && isdigit(nPtr[6]) && isdigit(nPtr[7]) && isdigit(nPtr[8]) && isdigit(nPtr[9]))
{
return 1; //return 1 if this is true
}
else{
return 0; //otherwise if its false return 0
}//end of inner else statement
}
else {
return 0; //otherwise if length exceeds 10 digits, then return 0
} //end of outer else statement
}
/*flush function, takes no input
and has no output*/
void flush_in (){
int ch; //defining local variables
while ((ch = fgetc (stdin))!= EOF && ch != '\n'){}
}
/*Contact information saving function
takes all contact information inputted in the
addnewcontact module, and prints them to the file*/
int filewrite (){
int u; //defining local variables,
struct student *pF;
struct student *pC=pF;
FILE *xPtr; //defining file pointer
xPtr = fopen ("contactlist.dat", "w"); //opening file for writing
for (u=1;u<i;u++){ //going through the entire file
fprintf (xPtr,"%s\n", pC->firstname); //writing first name
fprintf (xPtr,"%s\n", pC->lastname); //writing last name
fprintf (xPtr,"%s\n", pC->address); //writing address
fprintf (xPtr,"%s\n", pC->postalcode); //writing postal code
fprintf (xPtr,"%s", pC->phone); //writing phone number
}
fclose (xPtr);//closing file
printf ("\nContact information saved successfully!\n"); //informing user that the process was a success
printf ("\n");
enterchoice (); //going back to the main menu
return 0;
}
/*Data display function,
outputs the last contact information
entered, takes input from addnewcontact module*/
int displaydata (struct student *pF){
//defining local variables
int j;
j=i-1;
struct student *pC = pF;
printf ("\n");
printf ("First name: ");
wordcap (pC->firstname); //capitalizing then printing last first name entered
printf ("Last name: ");
wordcap (pC->lastname); //capitalizing then printing last last name entered
printf ("Address: %s\n", pC->address); //printing last address entered
printf ("Postal code: ");
formatpostalcode (pC->postalcode); //formatting then printing last postal code entered
printf ("Phone number: ");
formatphonenumber (pC->phone); //formatting then printing last postal code entered
printf ("\n");
enterchoice(); // going back to main menu
}
/*Loading function, takes input saved into the file
from the filewrite function and reads it from the file
then prints it to the user*/
int loaddata (){
//declaring local variables
int u=1;
FILE *cPtr; //defining file pointer
cPtr = fopen ("contactlist.dat", "r"); //opening file for reading
if (cPtr == '\0'){ //if file is empty, then inform user
printf ("Error, File is empty\n");
}
else{ //otherwise read from file and print
//while the end of the file is not reached, and the maximum number of records has not been reached either, print the information
while (!feof(cPtr) && u < i)
{
fgets (contact[u].firstname, 40, cPtr); //read the first name
wordcap (contact[u].firstname); //captitalize it then print it
fgets (contact[u].lastname, 40, cPtr); //read last name
wordcap (contact[u].lastname); //capitalize it then print it
fgets (contact[u].address, 100, cPtr); //read address
printf ("%s\n", contact[u].address); //print address
fgets(contact[u].postalcode, 7, cPtr); //read postal code
formatpostalcode (contact[u].postalcode); //format it then print it
fgets (contact[u].phone, 10, cPtr); //read phone number
formatphonenumber (contact[u].phone); //BUG: prints first contacts phone number incorrectly, then prints correctly for other contacts
printf ("\n");
u++;
cPtr++;
}
fclose (cPtr);
}
enterchoice ();
}
/*Final save function,
prompts user if he/she wants
to save any unsaved changes in his/her
contact information, takes choice as input,
writes unsaved information to file*/
int finalsave ()
{
//declaring local variables
char choice; //declaring choice variable
int u; //declaring counter
FILE *outfile; //declaring file pointer
printf ("Would you like to save your contacts before leaving? "); //prompting user if he/she wants to save unsaved changes
scanf ("%s", &choice); //reading users response
if (choice == 'y') //if user responds y as in yes, then open the file, and save all contact information
{
outfile = fopen ("contactlist.dat", "w"); //opening file
for (u=1;u<i;u++){ //going through all contents of file
fprintf (outfile,"%s\n", contact[u].firstname); //writing first name
fprintf (outfile,"%s\n", contact[u].lastname); //writing last name
fprintf (outfile,"%s\n", contact[u].address); //writing address
fprintf (outfile,"%s\n", contact[u].postalcode); //writing postal code
fprintf (outfile,"%s\n", contact[u].phone); //writing phone number
} //end of for loop
fclose (outfile); //closing file
printf ("\nContact information saved successfully!\n"); //inform user operation was successful
printf ("\n");
}
printf ("Bye!\n");
return 0; //return 0 indicating successful termination
}
/*Formatting phone number module
Takes passed phone number, and puts area code
in brackets, then puts a space, and a hyphen character
3 numbers after that*/
void formatphonenumber (char *gPtr){
//declaring counters
int k, j, l;
putchar ('('); //inputting opening bracket before first 3 numbers
for (k = 0; k < 3; k++){ //going through first 3 numbers
putchar(gPtr[k]); //print them
} //end of for loop
putchar (')'); //input a closing bracket after 3 numbers have been printed
putchar (' '); //input a space after the closing bracket has been printed
for (j = 3; j < 6; j++){ //going through 3 more numbers, printing as we go
putchar(gPtr[j]);
}
putchar ('-'); //after 3 more numbers have been printed, input a hyphen
for (l = 6; l < 10; l++){ //go through the last 4 numbers, print as we go
putchar(gPtr[l]);
}
printf ("\n");
}
/*formatting postal code,
works almost same way as the
formatphonenumber function;
takes passed postal code,
capitalizes the letters and inputs a
hyphen after 3 characters have
been printed*/
void formatpostalcode (char *hPtr){
//declaring local variables
int f, g; //declaring counters
char c, k, d;
for (f = 0; f <3; f++){ //going through first 3 characters, converting to uppercase and printing as we go
c = toupper (hPtr[f]);
putchar (c);
} //end of for loop
putchar ('-'); //input hyphen after 3 characters have been printed
for (g = 3; g < 6; g++){ //go through last 3 letters, converting to uppercase and printing as we go
c = toupper (hPtr[g]);
putchar (c);
} //end of for loop
printf ("\n");
}
/*Search function, takes
last name as input, and ouputs
the record with a last name
that matches the inputted last name*/
void search (){
//declaring local variables
char lname[40]; //declaring last name variable
int u, choice; //counter and choice variables, respectively
printf ("Please enter contacts last name: "); //prompting user to input last name
scanf ("%s", lname);
FILE *outfile; //declaring file pointer
outfile = fopen ("contactlist.dat", "rt"); //opening file
for (u=0; u<=i;u++){ //going through contents of file
if (strcmp (lname, contact[u].lastname)== 0){ //if last name is found, then print all information that accompanies it
printf ("\nFirst Name: ");
wordcap (contact[u].firstname);
printf ("Last Name: ");
wordcap(contact[u].lastname);
printf ("Address: %s\n", contact[u].address);
printf ("Postal Code: ");
formatpostalcode (contact[u].postalcode);
printf ("Phone Number: ");
formatphonenumber (contact[u].phone);
}
fclose (outfile); //closing file
}
printf ("\n");
enterchoice(); //back to main menu
}
/*wordcap function, words similarily to
formatphonenumber and formatpostalcode,
takes passed word as input, and outputs
its first letter capitalized*/
void wordcap (char aPtr[]){
//declaring local variables
int k, l; //declaring counters
char c;
char d;
int length = ((int) strlen(aPtr)); //finding length of passed word
for (k = 0; k < 1; k++){ //going to beginning of the string and capitalizing first character
c = toupper (aPtr[k]);
putchar (c); //printing capitalized character
}
for (l = 1; l < length;l++){ //going through rest of string and changing everything to lower case along with it
d = tolower (aPtr[l]);
putchar(d);
}
printf ("\n");
}
Thanks for all the help u guys gave me so far by the way,
like i understand the concept of a linked list but i dont get how to implement it in my code to replace things like contact[u].firstname
and contact[u].lastname
..
thanks in advance