Thread: Data Structure Eror

  1. #1
    Registered User
    Join Date
    Sep 2008
    Location
    Jakarta
    Posts
    18

    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 ---------------------------------------

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    compile error: undefined reference to main_menu(). You have it only once in your code. Where is the function actually defined?

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    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.

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

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