C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 01-06-2009, 09:06 AM   #1
Registered User
 
Join Date: Sep 2008
Location: Jakarta
Posts: 16
Data Structure Eror

This is a Simple Personal Information Manager (PIM) program that i made.
But there is some error in it that i just can't fixed !
Can somebody just check and see where is wrong ?

At First, it works normally, it can add task, delete task, edit task and view task.
but after :
- add 2 or 3 task
- delete one of them
- add another one
- edit one of the task
- and presto ! it can no longer delete any task.

this is my code, it kinda long.... but please just see what is wrong.
I think personally the error is in the Editing part (TaskEdit) or the deleting part (Taskdelete). The problem is, the "temp.dat" file i use as a temporary data holder, Won't close. But anyways... this is my code :

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


/* Function Prototype for Task Manager */
void TaskAdd();
void TaskMainTask ();
void Taskprint();
void TaskView();
void TaskDelete ();
void TaskDeleteTitle ();
void TaskEmpty (FILE *delPtr, char check[], char data[]);
void TaskPrintFile();
void TaskEdit ();
void TaskEditTitle ();
void TaskChange (FILE *editPtr, char check[],char data[]);
void TaskPreview ();
void TaskLook ();

/*initiate structure for Task Manager*/
struct taskManager { // strat of struct
	char title[30];
	char details[130];
	char startDate[80];
	char endDate[80];
}TaskManager; // end of struct and assign struct as TaskManager

int main()
{
    
    TaskMainTask();
}
/*Start of Main Task*/
void TaskMainTask()
{//Start of maintask

	int choice; //set interger choice
	int counter; // set interger counter
	
	counter = 1; // set counter to 1
	
    
	
	while ( counter != 0) { // start while
		
		system("cls");
		/*Main Menu*/
		printf ("Task Manager\n\n");
		printf ("What Do You Want To Do ?\n");
		printf ("[1]. Add Task/Project\n");
		printf ("[2]. Edit Task/Project\n");
		printf ("[3]. View Task/Project\n");
		printf ("[4]. Print the Task/Project To a File\n");
		printf ("[5]. Delete the Task/Project\n");
		printf ("[6]. Back to Main Menu\n");
		printf ("[7]. Exit The Program\n");
		scanf ("%d", &choice);
		
		/*if entry not valid*/
		if (choice < 1 || choice > 8) { // start if
			printf ("Entry Not Valid !!\n");
			printf ("Please Enter 1-7");
			getchar();
		}//end If
		
		/*if Entry was valid*/
		else { // start else
			switch (choice) { // start switch
				case 1: 
					TaskAdd(); // go to add
					break;
				case 2 :
					TaskEdit (); // go to edit
					break;
				case 3 :
					TaskLook(); // go to look
					break;
				case 4 :
					TaskPrintFile(); // go to print_file
					break;
				case 5 :
					TaskDelete (); // go to delete
					break;
				case 6 :
					main_menu();
					break;
				case 7 :
					exit (1); // exit program
					break;
			} // end switch
		
		}// End Else
	
	} // End While

} // End MainTask

/*adding Task*/	
void TaskAdd ()
{ // start of add

	FILE *cfPtr;//information.dat file pointer
	int choice2;//variable for storing the user choice	
	char buffer[10];
	
	//fopen opens the file; exits if file cannot be opened
	if ((cfPtr = fopen ("Task.dat","ab")) == NULL ){ // start of if
		printf ("Filed Could not be Opened\n");
	}// end if
	
	/*adding information */
	else { // start of else
	 
		system ("cls"); 
		
		printf ("=======Add New Task/Project========\n");
		printf ("\nEnter The Title :\n");
		gets (buffer);
		gets (TaskManager.title);
		printf ("\nNotes and Details of The Task/Project (130 Character) : \n");
		gets (TaskManager.details);
		printf ("\nStart Date ( mm/dd/yy ) : ");
		gets (TaskManager.startDate);
		printf ("Due Date (mm/dd/yy) : ");
		gets (TaskManager.endDate);
		
		/*write the record in the file*/
		fwrite (&TaskManager, sizeof(TaskManager), 1 , cfPtr);
		
		fclose (cfPtr); // closes the file
		
		printf ("\nProject Saved\n");
		printf ("Press [Enter] To Continue\n");
		getchar();
		system ("cls");
		TaskPreview (); // showing the outcome
		printf ("Do You want to Add a New Task ?\n[1].Yes\n[2].No\n");
		scanf ("%d", &choice2);
		
		if ( choice2 == 1 ) { // start of if
			TaskAdd ();
		} // end of if
		else if (choice2 == 2) { // start of else if
			TaskMainTask ();
		}// end of else if		
	}// end of else

} // end of else

/*Function Preview; Printing the result for the user*/
void TaskPreview ()
{ // start of preview
     printf ("%43s\n\n","=====Task Preview=====");
     printf ("%30s%15s%15s\n","Title","Start Date","Due Date");
     printf ("%30s%15s%15s\n",TaskManager.title, TaskManager.startDate, TaskManager.endDate);
     printf ("\n%10s\n%10s\n\n", "Notes / Details :", TaskManager.details);
     printf ("\n");
} // end of preview    

/*Function print; printing the result in diffrent format*/
void Taskprint()
{ // start of print
     printf("%30s%15s%15s\n", TaskManager.title, TaskManager.startDate, TaskManager.endDate);
     printf("\n");
} // end of print

/*Start of function view*/
void TaskView ()
{ //start of view

	FILE *viewPtr; // Task.dat file pointer
	
	/*Opening the file*/
	if ((viewPtr = fopen ("Task.dat", "r")) == NULL) { // start of if
		printf ("File Could not be Openend.\n");
	} // end of if
	
	else {// start of else
		rewind(viewPtr); // sets pointer to begining of file
		
		system ("cls");
		printf("%30s%15s%15s\n", "Title", "Start Date", "End Date");
		/*Resd trough file stream */
		while ( !feof(viewPtr)) { // start of while
			/*set all the structure memory to NULL */
			TaskManager.title[0] = '\0';
			TaskManager.details[0]= '\0';
			TaskManager.startDate[0]= '\0';
			TaskManager.endDate[0]= '\0';
			
			/*Read from file*/
			fread (&TaskManager, sizeof(TaskManager), 1, viewPtr);
			if (TaskManager.title[0] != '\0') { // start of if
				Taskprint ();
            } // end of if
			else { // start of else
				break;
			} // end of else	
		
		} // end of while
		fclose(viewPtr);
	}// end of else
	getchar();
} // end of view

/*function delete; header to delete*/
void TaskDelete ()
{ // start of delete

	int choice;
	system("cls");
	/*Ask The user*/
	printf ("what do you want to do ?\n");
	printf ("[1]. Delete Task\n");
	printf ("[2]. Return To Main Menu\n");
	printf ("Please Choose an Option :\n");
	scanf ("%d", &choice );
	
	/*if the input is invalid*/
	if (choice < 1 || choice > 2 ) { // start of if
		printf( "Invalid Input !\n" );
		system("pause");
		TaskMainTask();
	} // end of if
	
	/*if the input is valid*/
	else { // start of else
		switch (choice) { // start of switch
			case 1 : // return to deleteTitle
				TaskDeleteTitle();
				break;
			case 2 : // back to Main Task
				TaskMainTask();
				break;
		} // end of switch
	} // end of else
	
	system("pause");

}// end of delete

/*start of deleteTitle function; part of delete*/
void TaskDeleteTitle ()
{ // start of deleteTitle
	
	FILE *cfPtr; // assign file pointer
	
	/*initiate variables*/
	int result;
	char checkTitle[20];
	int choice1;
	int choice2;
	
	system("cls");
	/*opening Task.dat file*/
	if ((cfPtr = fopen ("Task.dat", "rb+")) == NULL ) { // start of if
		printf ("File Couldn't be found");
	} // end of if
	else { // start of else
        TaskView (); // View the current file
		printf ("Enter the Title you want to delete :\n");
		gets (checkTitle);
		
		/*Read Through the file*/
		while (fread(&TaskManager, sizeof(TaskManager), 1, cfPtr) 
		&& strcmp (checkTitle, TaskManager.title));
		
		/*compareing the strings*/
		result = strcmp (checkTitle, TaskManager.title);
		if (result != 0) { // start of if
			printf("Record Not Found !\n\n");
		} // end of if
		else { // start of else
			system("cls");
			printf("Record is found !\n\n");
			
			TaskPreview ();
			
			/*aking the user*/
			printf ("Do You want to delete this Note ?\n");
			printf ("[1]. Yes\n[2]. No\n");
			printf ("Choose an Option : ");
			scanf ("%d", &choice1);
			
			/*if the input is invalid*/
			if (choice1 < 1 || choice1 > 2 ) { // start of if
				printf ("Input Invalid !");
				getchar ();
				TaskMainTask ();
			} // end of if
			
			/*if the input is Valid*/
			else { // start of else
				switch (choice1) { // start of switch
					case 1 : // argument #1
						TaskEmpty(cfPtr, checkTitle, TaskManager.title);
						printf ("Note Deleted !\n");
						
					    break; // break case 1
                   
				case 2 : // argument # 2
					
					TaskMainTask();
					break; // break case #2
				} // end of switch
			} //end of else
		} // end of outer else
			
			fclose (cfPtr);
	} // end the most outer else
} // end of delete Title

/*Start of Function empty*/
void TaskEmpty (FILE *delPtr, char check[], char data[])
{ // start of empty

	FILE *temp; // file pointer
	
	temp = fopen ("temp.dat", "w"); // set temp to open file temp.dat
	
	rewind(delPtr); // set pointer to begining of file
	
	while (fread(&TaskManager, sizeof(TaskManager), 1, delPtr)) { // start of while
		if (strcmp (check, data)) { // start of if
			fwrite ( &TaskManager, sizeof (TaskManager), 1, temp); //write to file
		} // end of if
	} // end of while
	
	fclose (delPtr); // closing file pointer
	fclose (temp); // closing temporary pointer
	remove ("Task.dat"); // delete task.dat
	
	rename ("temp.dat", "Task.dat"); // rename temp.dat to task.dat
	/*set structure to NULL*/
	TaskManager.title[0] = '\0';
	TaskManager.details[0] = '\0';
	TaskManager.startDate[0] = '\0';
	TaskManager.endDate[0] = '\0';
	
} // end of empty

/*Start of function print_file*/
void TaskPrintFile()
{ // start of print_file
     
	 FILE *viewPtr; // Set File Pointer
     FILE *printPtr; // set File Pointer

     system("cls");
	 
	 /*if the record cannot be found*/
     if((viewPtr=fopen("Task.dat","r"))== NULL){ // start of if
        printf("File could not be opened.\n");
     }//end if
     
     /*if the record cannot be found*/     
     if((printPtr=fopen("Task2.txt","w"))== NULL){ // start of if
        printf("File could not be opened.\n");
     }//end if
     
     else{ // start of else
     rewind(viewPtr); // set pointer to the start of file
     
	 /*set the array to NULL*/
     while(!feof(viewPtr)){ // start of while
        TaskManager.title[0] = '\0';
		TaskManager.details[0] = '\0';
		TaskManager.startDate[0]='\0';
		TaskManager.endDate[0] = '\0';
        
		/*read from file*/
        fread(&TaskManager, sizeof(TaskManager),1,viewPtr);
        if(TaskManager.title[0]!='\0'){ // start of if
            fprintf (printPtr,"%43s\n\n","=====Task Print=====");
            fprintf (printPtr,"%30s%15s%15s\n","Title","Start Date","Due Date");
            fprintf (printPtr,"%30s%15s%15s\n",TaskManager.title, TaskManager.startDate, TaskManager.endDate);
            fprintf (printPtr,"\n%10s\n%10s\n\n", "Notes / Details :", TaskManager.details);
            fprintf (printPtr,"\n");
			
        } // end of if
        else { // start of else
		
        break;
			} // end of else
        
		}//end while
		
        printf("The informations have been printed on a file\n\n");
        fclose(viewPtr);
        fclose(printPtr);
	
	}//end else
	
     getchar();
     getchar();
 
} // end of print_file

/*start of edit*/
void TaskEdit()
{ // start of edit
     int choice;
     
     system("cls");
	 
	 /*Asking for user input*/
     printf("\n\n\nWhat Do You Want To do ?\n");
     printf("[1]. Edit by title\n");
     printf("[2]. Return to menu\n");
     printf("\nPlease choose an option : ");
     scanf("%d", &choice);
     
	 /*if the input was invalid*/
     if(choice<1 || choice>2){ // start of if
                   printf("Please only enter 1-2!\n");
                   system("pause");
                   }//end inner if
     switch (choice){ // start of switch
            case 1 : // case #1
				 TaskEditTitle(); 
				 break;
            case 2 : // case #2
                 system ("cls");
                 TaskMainTask(); 
                 break;
         
     }//end switch
    
     
}//end edit function

/*start of e_title*/
void TaskEditTitle()
{ // start of e_title
    
     FILE *cfPtr; // assign a FILE pointer
	 int result;
     char check_task[20];
     int choice1;
     
	/*if file can't be opened*/
	if((cfPtr = fopen("Task.dat","rb+"))==NULL){
		printf("File could not be opened.\n");
	}//end if
               
	else{ // start of else
		system ("cls");
		TaskView ();
		printf("Enter the title you wish to change : ");
		gets(check_task);
	
		/*Read from file*/
		while(fread(&TaskManager,sizeof(TaskManager), 1, cfPtr) 
		&& strcmp(check_task, TaskManager.title));
        
		/*comparing the strings*/
		result = strcmp(check_task, TaskManager.title);
		if(result!=0)
		{// start of if
			system("cls");
			printf("==SEARCHING==\n");
			system("pause");
			system("cls");
			printf("Record not found!\n\n");         
		} // end of if
		
		else{ // start of else
			
			system("cls");
			printf("==SEARCHING==\n");
			system("pause");
			system("cls");
			printf("Record found!\n\n");
                   
			TaskPreview();
			
			/*ask the user for input*/
			printf("Do you want to edit this record?\n");
			printf("[1]. Yes / [2]. No\n");
			printf("Choose an option : ");
			scanf("%d", &choice1);
            
			/*if the input is invalid*/
			if(choice1<1 || choice1>2){
				printf("Please only enter 1-2!\n");
				system("pause");
				TaskEditTitle();
			}//end inner if
			
			/*If the input is valid*/
			else { // start of else
				switch (choice1){ // start of switch
				case 1 : // case #1
					TaskChange(cfPtr, check_task,TaskManager.title);
					printf("\nRecord edited!\n");
					printf("Press [ENTER] to Continue\n");
					system("pause");                    
					break; // break from outer case#1
                   
				case 2 : // case #2
					TaskMainTask();
					break;
				}//end switch 
			}//end inner else                
		}//end else
               
               
		fclose(cfPtr);  // closing the pointer   
	}//end else     
	
}// end of e_title

/*start of change*/
void TaskChange(FILE *editPtr, char check[],char data[])
{ // start of change

     char buffer[10];
	 
     rewind(editPtr); // set the pointer to the start of file
	 
	 /*reading the file*/
     while(fread(&TaskManager, sizeof(TaskManager), 1, editPtr) && strcmp(check,data));
     
	 /* Changing the content */
     if(!strcmp(check,data)){ // start of if
		
		system("cls");                        
		printf("\nEnter Title : ");
		gets(buffer);
		gets(TaskManager.title);
		printf("\nDetails/Notes : \n ");
		gets(TaskManager.details);
		printf("\nStart Date ( mm/dd/yy ): ");
		gets(TaskManager.startDate);
		printf("End Date ( mm/dd/yy ): ");
		gets(TaskManager.endDate);
		fseek(editPtr, ftell(editPtr) - sizeof(TaskManager),0);     
		fwrite(&TaskManager, sizeof(TaskManager), 1, editPtr);
     
     }//end if
	 
     fclose(editPtr); // close the pointer

} // end of change

/*start of look*/
void TaskLook ()
{
     
	 FILE *lookPtr; // set a File pointer
     
	 /*Assigning variable*/
	 int result;
	 char checkTitle[20];
	 int choice1;
	 
     /* opening the file*/
    if((lookPtr = fopen("Task.dat","rb+"))==NULL){ // start of if
		printf("File could not be opened.\n");
	}//end if
               
	else{ // start of else
		
		system ("cls");
		
		TaskView ();
		
		printf("Enter the title you wish to view :\n");
		gets (checkTitle);
		
		/*read through the file*/
		while (fread(&TaskManager, sizeof(TaskManager), 1, lookPtr) 
			&& strcmp (checkTitle, TaskManager.title));
		
		/* comparing the strings */
		result = strcmp (checkTitle, TaskManager.title);
		
		if (result != 0) { // start of if; if the string not found
			printf("Record Not Found !\n\n");
			system("pause");
		} // end of if
		
		else {// start of else; if the strings are matched
		
			system("cls");
			
			printf("Record is found !\n");
			
			TaskPreview ();
			
			/*asking user input*/
			printf ("Do You want to view another task ?\n");
			printf ("[1]. Yes\n[2]. No\n");
			printf ("Choose an Option : ");
			scanf ("%d", &choice1);
			
			/*if the input invalid*/
			if (choice1 < 1 || choice1 > 2 ) {// start of if
				printf ("Input Invalid !");
				getchar ();
				TaskMainTask ();
			} // end of if
			
			else { // start of else
                 switch ( choice1 ) { // start of switch
					case 1:// case #1
                      system ("cls");
                      TaskLook ();
                      break;
					case 2: // case #2
                      system("cls");
                      TaskMainTask ();
                      break;
				 } // end of switch
			} // end of else
		} // end of outer else
		
		fclose(lookPtr);
	} // end of outest else
  
}// // end of look

//---------------------- end task ---------------------------------------
prominababy is offline   Reply With Quote
Old 01-06-2009, 09:23 AM   #2
Registered User
 
C_ntua's Avatar
 
Join Date: Jun 2008
Posts: 1,134
compile error: undefined reference to main_menu(). You have it only once in your code. Where is the function actually defined?
C_ntua is offline   Reply With Quote
Old 01-06-2009, 09:33 AM   #3
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Code:
		if ( choice2 == 1 ) { // start of if
			TaskAdd ();
		} // end of if
		else if (choice2 == 2) { // start of else if
			TaskMainTask ();
		}// end of else if
You are essentially looping by recursion. Whilst you may not discover any problems with that in your current code, it is definitely not the right way to do things.

Code:
		switch (choice) { // start of switch
What makes you think that if the reader can not read "switch (choice) {" that they will understand better from "// start of switch"? Comments are meant to make the code understandable, nor trivially rephrase a the stuff on the left of it.

You may find that having "end if ..." comments are sort of helpful, but really, it should be covered by your indentation, and if the code is so long & complex that it's not clear to see, then you PROBABLY should refactor it so that you make some of the code in a large block into a separate function.

Code:
	FILE *cfPtr; // assign file pointer
This comment is absolutely incorrect - there is no assignment, - it's just a variable declaration of a file-pointer. FILE * clearly indicates that, so there is REALLY no reason to have a comment for that. If you really want to have a comment for the cfPtr variable, perhaps you should say "task.dat" file pointer, or some such. Of course, changing the name to "taskFile" would make that comment obsolete too.

Code:
		gets (TaskManager.endDate);
I know you are not to blame, but gets() is probably the ABSOLUTELY MOST STUPID function in all of the C runtime library - because if someone falls asleep pressing the 'a' key, an then hits enter, your program will crash.

Code:
		while(fread(&TaskManager,sizeof(TaskManager), 1, cfPtr) 
		&& strcmp(check_task, TaskManager.title));
        
		/*comparing the strings*/
		result = strcmp(check_task, TaskManager.title);
		if(result!=0)
		{// start of if
			system("cls");
			printf("==SEARCHING==\n");
			system("pause");
			system("cls");
			printf("Record not found!\n\n");         
		} // end of if
So after you have searched the file, you say "SEARCHING", then wait for the user to press a key... Very meaningful... And if you MUST do this, perhaps only duplicating the code that says "Record [not] found", rather than all four lines of code.

Also, you could put (result = strcmp(...) inside the while, avoiding a second strcmp to see if you ACTUALLY found it...

And it seems to me that you could make a function of "find task with a particular title".


Code:
		fseek(editPtr, ftell(editPtr) - sizeof(TaskManager),0);
Does that last zero mean SEEK_CUR?

Code:
						TaskEmpty(cfPtr, checkTitle, TaskManager.title);
...
void TaskEmpty (FILE *delPtr, char check[], char data[])
{ // start of empty
...
	while (fread(&TaskManager, sizeof(TaskManager), 1, delPtr)) { // start of while
		if (strcmp (check, data)) { // start of if
			fwrite ( &TaskManager, sizeof (TaskManager), 1, temp); //write to file
...
So, you are comparing TaskManager.title with checkTitle, and if they don't match, you write to the file. Seeing as the Taskmanager.title is the one you found from searching for the user entered title, and the checkTitle is the title the user entered, do you believe it will actually differ very often?

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 01-06-2009, 09:35 AM   #4
Registered User
 
C_ntua's Avatar
 
Join Date: Jun 2008
Posts: 1,134
On other note, I managed to make your program in a deadlock. I believe you have some bugs in the input method.
Try debugging the program. Like see if it enters the delete functions when you try to delete and it doesn't delete.
If it does try to print various variables (or use debugger) and see from there.
C_ntua is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
pthread question how would I init this data structure? mr_coffee C Programming 2 02-23-2009 12:42 PM
Data structure implementation fkheng C Programming 3 07-31-2003 07:44 AM
can't insert data into my B-Tree class structure daluu C++ Programming 0 12-05-2002 06:03 PM
Tab Controls - API -KEN- Windows Programming 7 06-02-2002 09:44 AM
Dynamic Data Structure -- Which one is better? Yin C++ Programming 0 04-10-2002 11:38 PM


All times are GMT -6. The time now is 04:10 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22