void display_list()
{
	shoes_node *current_ptr;
	current_ptr = head_ptr; // move current_ptr to head of list
	
	if(current_ptr == NULL)
	{
		cout<<"\n\t\t\tNO RECORDS TO BE DISPLAY \n"<<endl;
	}
	
	else(current_ptr != NULL);
	{
			cout<<"\n\t\t\t ****************************\n"<<endl;
			cout<<"\n\t\t\t        SHOES RECORDS        \n"<<endl;
			cout<<"\n\t\t\t ****************************\n"<<endl;
        	do
        	{
        		cout<<"\n\t\t\t SHOES'S ID	: "<<current_ptr->idkasut<<endl;
				cout<<"\n\t\t\t SHOES'S BRAND	: "<<current_ptr->jenama<<endl;
				cout<<"\n\t\t\t SHOES'S PRICE	: "<<current_ptr->harga<<endl;
				cout<<"\n\t\t\t SHOES'S SIZE	: "<<current_ptr->saiz<<endl;
				cout<<endl;
        
				current_ptr = current_ptr->next; //set current ptr to next node
        	}
				while (current_ptr->next != NULL); //loop until the end of list
	}
}

This code give me problem.
When I display for the 1st time is ok.
After I add the records more than 2 or 3 the program will stop automatically.
Any one can explain and solve it??

Recommended Answers

All 4 Replies

This are the full code

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <stdlib.h>

using namespace std;

struct shoes_node
{
	string idkasut;
	string jenama;
	string harga;
	string saiz;
	
	shoes_node*next;
};

shoes_node*head_ptr;
shoes_node*current_ptr;

void handle_choice(int choice);
void add_record();
void insert_node(shoes_node *new_rec_ptr);
shoes_node *position_insertion_point(string idkasut);
void make_node_new_head(shoes_node *new_rec_ptr);
void add_node_to_end(shoes_node *new_rec_ptr);
void move_current_to_end();
void display_list();
void search_by_idkasut();
void delete_record();
int verify_delete();
void delete_node(shoes_node *previous_ptr);
void delete_head_of_list();
void delete_end_of_list(shoes_node *previous_ptr);
void delete_middle_of_list(shoes_node *previous_ptr);
void delete_list();
void write_list_to_file();
void load_list_from_file();

//main function
int main()
{
	int choice;
	
	head_ptr = NULL;  //initialize head pointer to NULL
	load_list_from_file();  //load data from the disk file into linked list
	do
	{ // display menu
	cout<<"\n\t\t\t ****************************\n"<<endl;
	cout<<"\n\t\t\t           WELCOME TO        \n"<<endl;
	cout<<"\n\t\t\t     AL-IKHSAN SHOES STORE   \n"<<endl;
	cout<<"\n\t\t\t ****************************\n"<<endl;
	cout<<"\n\t\t\t 0. Exit program\n"<<endl;
	cout<<"\n\t\t\t 1. Add record\n"<<endl;
	cout<<"\n\t\t\t 2. Display all records\n"<<endl;
	cout<<"\n\t\t\t 3. Search for shoes by id\n"<<endl;
	cout<<"\n\t\t\t 4. Delete record\n"<<endl;
	cout<<"\n\t\t\t Please enter your choice : "<<endl;
	cin>>choice;
	handle_choice(choice); // call function to direct flow based on choice
	} 
	while(choice !=0); /// repeat menu until user chooce to exit
	return 0;
} // end of main function

//function to direct program flow based on user's choice
void handle_choice(int choice)
{
	switch(choice)  //choice is passed into the function by values
	{
		case 0: //if choice was to exit
		write_list_to_file(); //save database to a file and
		cout<<endl;
		cout<<"\n\t\t\t ____________________________\n"<<endl;
		cout<<"\n\t\t\t           THANK YOU         \n"<<endl;
		cout<<"\n\t\t\t      PLEASE COME AGAIN      \n"<<endl;
		cout<<"\n\t\t\t ____________________________\n"<<endl;
		break;
		case 1: //If choice was to add a record to the database
		add_record(); //call function to add a record to the linked list
		break;
		case 2: //if choice was to display all records in the database
		display_list(); //call function to display a record in the linked list
		break;
		case 3: //if choice was to search for a records in the database
		search_by_idkasut(); //call function to search a record by id kasut
		break;
		case 4: //if choice was to delete a records in the database
		delete_record(); //call a function that searches for record by id kasut and delete it
		break;
		default: //if any other (invalid) choice was entered
		cout<<"\n\t\t\t Invalid choice\n"<<endl;
		break;
	}
} //end of function handele_choice


//Function to add record to the linked list

void add_record()
{
	shoes_node*new_rec_ptr; //declare temporary pointer for the new node
	new_rec_ptr= new shoes_node; // allocate memory for a nwe node and 
								// initialize pointer to point to it
								
	if(new_rec_ptr !=NULL) //if no error allocating memory, get data and insert node
	{
		//get idkasut, jenama, harga and saiz
		cin.ignore(80,'\n');
		cout<<"\n\t\t\t ____________________________\n"<<endl;
		cout<<"\n\t\t\t       ENTER A NEW RECORD    \n"<<endl;
		cout<<"\n\t\t\t ____________________________\n"<<endl;
		cout<<"\n\t\t\t Shoes's ID : ";
		getline(cin,new_rec_ptr->idkasut);
		cout<<"\n\t\t\t Shoes's brand : ";
		getline(cin,new_rec_ptr->jenama);
		cout<<"\n\t\t\t Shoes's Price : ";
		getline(cin,new_rec_ptr->harga);
		cout<<"\n\t\t\t Shoes's size : ";
		getline(cin,new_rec_ptr->saiz);
		
		insert_node(new_rec_ptr);
	}
	else //if error occured allocating memory, display warning and do not create node
	{
		cout<<"\n\t\t\t Warning: Memory error. New record cannot be added.\n";
	}
}// end of function add_record

//Function to insert new node into correct position in list
void insert_node(shoes_node*new_rec_ptr)
{
	shoes_node*before_ptr;
	shoes_node*after_ptr;
	
	if(head_ptr == NULL)
	{							//if no nodes exist, make the node the head
		new_rec_ptr->next = NULL; 
		head_ptr = new_rec_ptr;
	}
	else
	{
		if(new_rec_ptr->idkasut < head_ptr->idkasut)
		{ //if new record comes before head, make it the new head
			make_node_new_head(new_rec_ptr);
		}
		else   //else, determine where the new node
		{      //should be inserted
			current_ptr = position_insertion_point(new_rec_ptr->idkasut);
			before_ptr = current_ptr;		// use pointers to keep track of nodes
			after_ptr = current_ptr->next;   //on each side of the insertion point
			
			if(after_ptr == NULL) //if after_ptr is NULL, the node needs to be added to the end of the list
			{
				add_node_to_end(new_rec_ptr);
			}
			else
			{
				before_ptr->next = new_rec_ptr;
				new_rec_ptr = after_ptr;
			}
		}
	}
} //end of function insert_node


//Function that positions current_ptr at the node before the position
//where the new node should be inserted

shoes_node *position_insertion_point(string idkasut)
{
	string temp_id;
	shoes_node *temp_ptr;
	
	if(head_ptr->next != NULL) //if more than one node existx, search the
	      						//list for the correct insertion point
	{
		current_ptr = head_ptr;
		temp_ptr = current_ptr->next;
		temp_id = temp_ptr->idkasut;
		//loop until the proper insertion point is located
		while((idkasut>temp_id) && (current_ptr->next != NULL))
		{
			current_ptr = temp_ptr;
			//check to see if the current node is the last node
			if(current_ptr->next != NULL)
			{
				temp_ptr = current_ptr->next;
				temp_id = temp_ptr->idkasut;
			}
		}
	}
	else
	{
		current_ptr = head_ptr;
	}
	return (current_ptr);
}//end of function_insertion_point

//Function that makes the node pointed to by new_rec_ptr the new head of the 
//linked list. It handles the special case of inserting at the front of the list

void make_node_new_head(shoes_node *new_rec_ptr)
{
	shoes_node *temp_ptr; //temporary pointer to keep track of the head
	
	temp_ptr = head_ptr;   //set temp_ptr to point at the current head
	new_rec_ptr->next = temp_ptr;  //make new nodes next pointer point to
	head_ptr = new_rec_ptr;        //current head and make new node the head
}

//function that adds a node to the end of the linked list. It handles
//the special case of inserting at the end of the list
void add_node_to_end(shoes_node *new_rec_ptr)
{
	new_rec_ptr->next = NULL; //set next node pointer of new node to NULL
	
	move_current_to_end(); //make sure current_ptr is at the end of the list
	current_ptr->next = new_rec_ptr; // place new node at the end of the list
}

//function that moves current_ptr to end of the linked list
void move_current_to_end()
{
	current_ptr = head_ptr; // move current_ptr to head of the list
	
	while(current_ptr->next != NULL) //transverse list until NULL is reached
	{
		current_ptr = current_ptr->next;
	}
}

void display_list()
{
	shoes_node *current_ptr;
	current_ptr = head_ptr; // move current_ptr to head of list
	
	if(current_ptr == NULL)
	{
		cout<<"\n\t\t\tNO RECORDS TO BE DISPLAY \n"<<endl;
	}
	
	else(current_ptr != NULL);
	{
			cout<<"\n\t\t\t ****************************\n"<<endl;
			cout<<"\n\t\t\t        SHOES RECORDS        \n"<<endl;
			cout<<"\n\t\t\t ****************************\n"<<endl;
        	do
        	{
        		cout<<"\n\t\t\t SHOES'S ID	: "<<current_ptr->idkasut<<endl;
				cout<<"\n\t\t\t SHOES'S BRAND	: "<<current_ptr->jenama<<endl;
				cout<<"\n\t\t\t SHOES'S PRICE	: "<<current_ptr->harga<<endl;
				cout<<"\n\t\t\t SHOES'S SIZE	: "<<current_ptr->saiz<<endl;
				cout<<endl;
        
				head_ptr = head_ptr->next; //set current ptr to next node
        	}
				while (head_ptr->next != NULL); //loop until the end of list
	}
}

//function that searched linked list for the first occurence of a given last id and display the record to the screen
void search_by_idkasut()
{
	string search_string; //character array for id to search for
	
	current_ptr = head_ptr;  //move current_ptr to head of list to begin search
	
	cin.ignore(80,'\n');
	cout<<"\n\t\t\t Enter the id for which you want to search\n"<<endl;
	getline(cin,search_string);
	
	//loop until search_string is found or end of list is reached
	while((current_ptr != NULL) && (current_ptr->idkasut != search_string))
	{
		current_ptr = current_ptr->next;
	}
	
	if(current_ptr != NULL)
	{
		cout<<"\n\t\t\t RECORD FOUND\n"<<endl;
		cout<<"\n\t\t\t SHOES'S ID	: "<<current_ptr->idkasut<<endl;
		cout<<"\n\t\t\t SHOES'S BRANDS	: "<<current_ptr->jenama<<endl;
		cout<<"\n\t\t\t SHOES'S PRICE	: "<<current_ptr->harga<<endl;
		cout<<"\n\t\t\t SHOES'S SIZE	: "<<current_ptr->saiz<<endl;
	}
	else
	{
		cout<<"\n\t\t\t NO MATCH FOUND\n"<<endl;
	}
}

//function that deletes individual nodes from the linked list
void delete_record()
{
	string search_string;
	shoes_node  *previous_ptr;
	
	previous_ptr = NULL;  //initialize previous_ptr to NULL
	current_ptr = head_ptr;
	
	cin.ignore(80,'\n');
	cout<<"\n\t\t\t Enter the id of shoes that you want to delete : \n";
	getline(cin,search_string);
	
	//loop to find matching record
	while ((current_ptr != NULL) && (current_ptr->idkasut != search_string))
	{
		previous_ptr = current_ptr; //a pointer must be maintened that
		current_ptr = current_ptr->next; // points to the node before the node to be deleted
	}
	if(current_ptr != NULL)
	{
		cout<<"\n\t\t\t RECORD FOUND\n"<<endl;
		cout<<"\n\t\t\t SHOES'S ID	: "<<current_ptr->idkasut<<endl;
		cout<<"\n\t\t\t SHOES'S BRANDS	: "<<current_ptr->jenama<<endl;
		cout<<"\n\t\t\t SHOES'S PRICE	: "<<current_ptr->harga<<endl;
		cout<<"\n\t\t\t SHOES'S SIZE	: "<<current_ptr->saiz<<endl;
			
		if(verify_delete()) //ask user if she/he wants to delete the record
		{ // if user wants to delete the record, delete the node that follows the
			delete_node(previous_ptr);	// one pointed to by previous_ptr
			cout<<"\n\t\t\t RECORD DELETED\n"<<endl;
		}
		else
		{
			cout<<"\n\t\t\t RECORD NOT DELETED\n"<<endl;
		}
	}
	else //if no match for the record found, display message
	{
		cout<<"\n\t\t\t NO MATCH FOUND. NO RECORD DELETED.\n"<<endl;
	}
}

//funtion to ask user to verify intention to delete the node
int verify_delete()
{
	char YesNo;
	
	cout<<"\n\t\t\t Do you wish to delete this record? (Y/N) \n"<<endl;
	cin>>YesNo;
	if((YesNo == 'Y') || (YesNo == 'y'))
	{
		return(1); // return TRUE if user wants to delete
	}
	else
	{
		return(0); //return FALSE if user does not want to delete
	}
}

//function that deleted node pointed to by current_ptr
void delete_node(shoes_node *previous_ptr)
{
	if(current_ptr == head_ptr)  //if node to be deleted is the head of the list
	{ // call a special function that delete the first node in the list
		delete_head_of_list();
	}
	else
	{
		if(current_ptr->next == NULL)
		{
			delete_end_of_list(previous_ptr);
		}
		else
		{
			delete_middle_of_list(previous_ptr);
		}
	}
}

//function that deletes the head of the list
void delete_head_of_list()
{
	current_ptr = head_ptr;
	if(head_ptr->next != NULL)
	{ //if more than one node is in the list, make second node in list the new head
		head_ptr = current_ptr->next;
	}
	else
	{
		head_ptr = NULL; // otherwise, just set head_ptr to NULL to signal that
		//the list is empty
	}
	delete current_ptr; //deallocate memory used by the deleted node
}

//functioon that delete the last node of the linked list
void delete_end_of_list(shoes_node *previous_ptr)
{
	delete current_ptr; //deallocate memory used by the deleted node
	previous_ptr->next = NULL; //make node before deleted node the end of list
	current_ptr = head_ptr; //set current+ptr to head to give it a value
}

//function that deletes a node from the middle of the list
void delete_middle_of_list(shoes_node *previous_ptr)
{
	//set the pointers of the nodes before and after the node to be deleted to
	//skip the node that is to be deleted
	previous_ptr->next = current_ptr->next; //deallocate memory used by the deleted node
	delete current_ptr; //make node before deleted node the end of list
	current_ptr = head_ptr; //set current+ptr to head to give it a value
}

//function that frees the memory used by the linke list
void delete_list()
{
	shoes_node * temp_ptr; //pointer used for temporary storage
	
	current_ptr = head_ptr; //move current_ptr to head of the list
	
	do //tranverse list, deleting as we go
	{
		temp_ptr = current_ptr->next; //set temporary pointer to point
		//to the remainder of the list
		delete current_ptr;
		current_ptr = temp_ptr;
	}
	while(temp_ptr != NULL);
}

//funtion to write linked list data to the data file
void write_list_to_file()
{
	ofstream outfile; //output file pointer
	
	outfile.open("senaraikasut.txt",ios::out); //open file for output
	
	if(outfile)  //if no error occured while opening the file
	{
		current_ptr = head_ptr; //set current_ptr to head of the list
		if(head_ptr !=NULL)
		{
			do
			{
				outfile<<"\n\t\t\t_____________________________________\t"<<endl;
				outfile<<"\n\t\t\t            SHOES RECORD             \t"<<endl;
				outfile<<"\n\t\t\t        AL-IKHSAN SHOES STORE        \t"<<endl;
				outfile<<"\n\t\t\t_____________________________________\t"<<endl;
				outfile<<"\n\t\t\t Shoes's ID	: \t"<<current_ptr->idkasut<<endl;
				outfile<<"\n\t\t\t Shoes's Brand	: \t"<<current_ptr->jenama<<endl;
				outfile<<"\n\t\t\t Shoes's Price	: \t"<<current_ptr->harga<<endl;
				outfile<<"\n\t\t\t Shoes's Size	: \t"<<current_ptr->saiz<<endl;
				outfile<<endl;
				
				current_ptr = current_ptr->next; //move current_ptr to next node
			}while(current_ptr != NULL);
		}
		outfile<<"\n\t\t\t END OF FILE \n"<<endl;
		outfile.close();
	}
		else
		{
			cout<<"\n\t\t\t Error opening file\n"<<endl;
		}
}

//function to load the linked list from the data file
void load_list_from_file()
{
	shoes_node * new_rec_ptr;
	ifstream infile; //input file pointer
	int end_loop = 0;
	
	infile.open("senaraikasut.txt",ios::in);
	
	if(infile)
	{
		do
		{
			new_rec_ptr = new shoes_node;
			if(new_rec_ptr != NULL)
			{
				getline(infile,new_rec_ptr->idkasut);
				
				if((new_rec_ptr->idkasut != "") && (new_rec_ptr->idkasut != "END OF FILE"))
				{
					getline(infile,new_rec_ptr->jenama);
					getline(infile,new_rec_ptr->harga);
					getline(infile,new_rec_ptr->saiz);
					insert_node(new_rec_ptr);
				}
				else
				{
					delete new_rec_ptr;
					end_loop = 1;
				}
			}
			else
			{
				cout<<"\n\t\t\t WARNING : Memory error.\n"<<endl;
				end_loop = 1;
			}
		}while(end_loop == 0);
		infile.close();
	}
	else
	{
		cout<<"\n\t\t\t No usable data file located. List is empty.\n"<<endl;
	}
}

I could be wrong, but I think the problem is in the insert_node() function, specifically this clause

else
			{
				before_ptr->next = new_rec_ptr;
				new_rec_ptr = after_ptr;
			}

I'm pretty sure you meant for this to be

else
			{
				before_ptr->next = new_rec_ptr;
				new_rec_ptr->next = after_ptr;
			}

I've also noted a problem in the display_list() function, with this clause:

head_ptr = head_ptr->next; //set current ptr to next node
        	}
				while (head_ptr->next != NULL); //loop until the end of list

It presumably should have been:

current_ptr = current_ptr->next; //set current ptr to next node
        }
        while (current_ptr->next != NULL); //loop until the end of list

However, I'm still getting the problem you describe, so these are not the cause of it. I'll keep looking into this for you.

Oh, and I noticed that you repeat the same display operations for the shoe records in several places, so you might want to add a function for it:

void write_record(ostream& output, shoes_node* rec)
{
        output<<"\n\t\t\t SHOES'S ID	: "<<rec->idkasut<<endl;
        output<<"\n\t\t\t SHOES'S BRANDS	: "<<rec->jenama<<endl;
        output<<"\n\t\t\t SHOES'S PRICE	: "<<rec->harga<<endl;
        output<<"\n\t\t\t SHOES'S SIZE	: "<<rec->saiz<<endl;
}

I think I've tracked down another issue to fix. In the display_list() function, you have a clause

if(current_ptr == NULL)
	{
		cout<<"\n\t\t\tNO RECORDS TO BE DISPLAY \n"<<endl;
	}
	
	else(current_ptr != NULL);
	{
                // and so forth...

The (current_ptr != NULL); part is redundant; you've already tested for the null pointer. worse, because it ends in a semi-colon, it causes that conditional statement to be treated as if it were the only thing guarded by the else statement. if you remove the (current_ptr != NULL); entirely, then it will prevent some of the segfaults you are experiencing.

I also suspect that the line

while (current_ptr->next != NULL); //loop until the end of list

should actually be

while (current_ptr != NULL); //loop until the end of list

... as you've already advanced the pointer at that stage.

Thanks a lot, this is a big help for me. I managed to solve the problem now :)

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.