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

edit: This is in c++, so replace 'new' with 'malloc()', 'delete' with 'free', and cout/cin with printf()/fgets()


instead of creating an array of structs like contact,

1. create a pointer of type 'contact'

2. everytime you need a new 'contact' node, create it by calling contact *cntcPtr = new contact; 3. After you create your new 'contact' nodes, be sure the last node you've created (if any) has a pointer in it, that points to the newly created node. sounds complicated, but it's really quite simple, and would probably look something like this:

PrevNode->next = cntctPtr;

4. You can populate your new node just by setting each attribute individually.

cout << "Enter Name: ";
cin >> cntctPtr->name;
etc..
...

5. Be sure that for your singly-linked list, that you always keep a dedicated pointer to the head node. If no head node, headptr = NULL;

6. For a singly linked list, it's probably a good idea to also have a dedicated pointer to the most newly created node.. 'PrevNode'

7. Also, make sure that if using tail-node insertion, that all newly created nodes 'next' pointer are initialized to NULL. If using head-node insertion, make sure that the first node you create, the 'next' pointer is initialized to NULL.

8. Here is a basic outline on how to traverse your singly-linked list if you wanted to look for specific items:

//Start at the front of the list and work to the back
contact *temp = headptr;

while(strcmp(temp->name, target_name) != 0 && temp != NULL)
{
     temp = temp->next;
}

//At this point, as long as temp does not equal NULL, 'temp' should be the node ye' are looking for.

9. be sure you delete your linked list when the user is done, or when the program terminates.

contact *temp = headptr;

while(headptr != NULL)
{
     headptr = temp->next;
     delete temp;
}

That's probably enough to get ye' started on your singly-linked list. Once you got the basics down, it's really not as hard as you think Just keep in mind that pointers are data types just like any other.. int's hold integer values.. floats hold floating point decimals.. char's hold ascii table values.. and pointers hold memory addresses. Piece of cake :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.