Thread: Finding and Replacing Data in a File

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    5

    Finding and Replacing Data in a File

    Hi,

    I'm having a real headache with this program and I'm about on the verge of tossing the keyboard through the monitor

    I have to build a program that allows us to store no more than 5 courses.
    The only operations that need to be carried out by the program are Add a course, View courses and Modify a course and when we modify a course, only the cost of the course needs to be modified and nothing else.

    I've gotten everything else to work but I can't fathom out how to modify the data.

    I'm not here because I want someone to do the work, what I want is for someone to explain to me in simple to understand english how to do it in a way that relates to the code I already have so I don't have to go back and modify it all.

    I'm sure there are better ways to do it, but due to time constrictions, this is the way it has to be done.

    Problem is I really don't understand passing stuff back and forth in C so I'm just going round and round and round and round. I've got myself to a stage now where I don't have a clue what is being passed to what or why anymore
    The code we have been given to follow is nigh on impossible to decipher or relate to and now I'm rather frustrated and stuck and not to mention stressed due to the time I have to finish.

    If someone wouldn't mind taking a look at my program so far to see if they can suggest what I need to do and a rough idea of how to do it....
    Also if they spot any mistakes I've maybe made, if they could point them out.
    No code needs to be offered, I want to do this myself but I need a little nudge in the right direction.

    Ideally, I would like my custom function modifyCourse() to deal with the modifying of the data

    Code:
    //C LIBRARIES HERE-------
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    
    //STRUCTURES HERE-------
    
    //Course structure
    typedef struct
    {        
       char courseCode[4];
       char courseName[30];
       int maxPlaces;
       float courseCost;
    } Course;
    
    //VARIABLES AND OTHER STUFF HERE-------
    
    //Build Course Array with a 5 courses limit
    Course courses[5];
    
    //Array / index position keeper
    int position = 0;
    
    //Specify file for storing course data
    char fileName[] = "courses.dat";
    
    //FUNCTION PROTOTYPES HERE-------
    void mainMenu();
    void viewCourses();
    void modifyCourse();
    void addCourse();
    void filterInput(Course courses[]);
    int readData(char fileName[], Course courses[], int position);
    void writeData(char fileName[], Course courses[], int position);
    void limitError(); //Extra function not in Structure Chart YET!!!
    void parseData(); //Extra function not in Structure Chart YET!!!
    
    
    //MAIN PROGRAM HERE-------
    int main()
    {
        //Calls main menu function - First port of call for the program user
        mainMenu();
    
        //System stuff - pauses program and returns an int value of 0 to main - (Tells the program it ran without fault)
        system("pause");
        return 0;    
    }
    
    //FUNCTIONS CONSTRUCTED HERE-------
    
    //Main Menu Function
    void mainMenu()
    {
         //stores the menu selection
         char mainMenuOption;
         system("cls");
         printf(" ----------------------------------\n");
         printf("| TRAINING COURSE SYSTEM -  ALPHA |\n");
         printf(" ----------------------------------\n\n");
         printf("PLEASE SELECT AN OPTION:\n\n");
         printf("(1) View All Courses\n");
         printf("(2) Modify Course\n");
         printf("(3) Add New Course\n\n");     
         mainMenuOption = getchar();
         _flushall();
         
         //Read data file when program starts and update position keeper according to number of course records stored
         //This only needs to be called here because it gathers and returns the data needed for all the other functions too!
         position = readData(fileName, courses, position);
    
         switch(mainMenuOption)
         {                 
              case '1': 
                   if(position <= 0)
                   {
                      system("cls");
                      printf("\nThere are no courses to display yet! \n\n");
                      system("pause");
                      mainMenu(); 
                   }
                   //Show the stored data                      
                   viewCourses();         
              break;
              
              case '2':
                   modifyCourse();
              break;
              
              case '3':
                   
                   if(position < 5)
                   {
                   addCourse();
                   }
                   else
                   {
                       //Show limit reached error
                       limitError();  
                   }
              break;
              
              default:
                   system("cls");   
                   printf("Invalid menu option selected.\n\n");
                   sleep(2000);
                   mainMenu();
              break;                                                                              
         }     
    }
    
    //View Stored Courses Function
    void viewCourses()
    {
        
        system("cls");
        printf(" ---------------------------\n");
        printf("| CURRENTLY STORED COURSES |\n");
        printf(" ---------------------------\n");
        //Mini storage limit check and warning
        if(position >= 5)
        {
              printf("\nWARNING: Trial Storage Limit Reached \n\n");        
        }
        printf("-------------------------------------\n");
        
        // performed if the students array contains at least one record
        parseData();
        
        printf("\n\n");
        printf("----------------------------------------------------\n");
        printf("Total courses stored: %i\n", position);
        printf("----------------------------------------------------\n\n");
        printf("WOULD YOU LIKE TO ADD A COURSE?\n\n");
        
        char addAnotherOption;
        scanf("%c", &addAnotherOption);
        _flushall();
        
        //Check storage limit before allowing the storing of more courses
        if(addAnotherOption == 'Y' || addAnotherOption == 'y')
        {
               if(position < 5)
               {
                     addCourse();      
               }
               else if(position >= 5)
               {  
                    //Show limit reached error
                    limitError();            
               }                                 
        }
        if(addAnotherOption == 'N' || addAnotherOption == 'n')
        {
               mainMenu();             
        }
            
    }
    
    //Modify Course Function     
    void modifyCourse()
    {
         system("cls");
         printf(" ------------------\n");
         printf("| MODIFY A COURSE |\n");
         printf(" ------------------\n\n");
         
         if(position <= 0)
         {
                  printf("No data to modify\n");   
         }
         
         parseData();
         
         printf("\n\nENTER THE COURSE CODE FOR THE COURSE TO BE CHANGED:\n");
         char courseCode[4]; 
         fgets(courseCode, sizeof(courseCode), stdin);
         _flushall();
         
         
         
         
         
         
    }
    //Add a Course Function
    void addCourse()
    {
          //Course entry data confirmation while loop option variable
          char preConfirmationOption;
          //Course entry data Confirmation while loop used for verification that the course details are correct before proceeding
          while(preConfirmationOption != 'y' && preConfirmationOption !='Y')
          {
             system("cls");  
             printf(" --------------\n");
             printf("| ADD A COURSE |\n");
             printf(" --------------\n\n");
          
             printf("You may add a course by following\n");
             printf("the on screen instructions below.\n\n");
          
             //Get courseCode
             printf("ENTER COURSE CODE:\n");
             fgets(courses[position].courseCode, sizeof(courses[position].courseCode), stdin);
             _flushall();
             
             //Get courseName
             printf("\nENTER COURSE TITLE:\n");
             fgets(courses[position].courseName, sizeof(courses[position].courseName), stdin);
             _flushall();
              
             //Get maxPlaces
             printf("\nENTER MAXIMUM NUMBER OF PLACES:\n");
             scanf("%i", &courses[position].maxPlaces);
             _flushall();
          
             //Get courseCost
             printf("\nENTER COURSE COST:\n");
             scanf("%f", &courses[position].courseCost);
             _flushall();
          
             //Show the current course entry and all its data - list number of courses e.g. 1 of 5, 2 of 5 etc
             //Prompt user to review and verify course data is correct before storing to file
             system("cls");
             
             //Filter the input here before showing the data for verification and saving
             //Now throwing incompatible pointer type argument!!!!!!!!!!!!!!!!!!!!!!!!!!
             filterInput(courses);
             
             //Display the course details entered back to user for verification
             printf("----------------------------------------\n");
             printf("| VERIFY COURSE DETAILS BEFORE STORING |\n");
             printf("----------------------------------------\n");
             printf("\t\n\n%s %s %i %c%0.2f\n\n\n", 
                            courses[position].courseCode, 
                            courses[position].courseName, 
                            courses[position].maxPlaces, 156, //156 Displays Pound Sterling Symbol
                            courses[position].courseCost
                            );
             //Prompt the user for some action to verify if the details are correct or incorrect               
             printf("IS THE COURSE DATA CORRECT? (Y or N):\n\n");
              
             //Get users verification input response
             scanf("%c", &preConfirmationOption);
             _flushall();
              
          }//End data verification while loop
          
          //Adds one to array position keeper variable - Keeps a track of the array position e.g. stored course entry 1, 2, 3 etc...
          position++;
          
          //Verification & storage confirmation message
          system("cls");
          printf("-------------------------------------\n");
          printf("| COURSE DETAILS HAVE BEEN VERIFIED |\n");
          printf("-------------------------------------\n\n");
          printf("The data has been written to file.\n");
              
          //Start the write data process
          writeData(fileName, courses, position);
          
          //display course count - TESTING PURPOSES
          printf("\nNumber of Courses Currently Stored: %i of 5\n\n", position);
              
          //Add another course option variable
          char addAnotherOption;
          
          //Prompt user to enter another course
          printf("WOULD YOU LIKE TO ADD ANOTHER COURSE?\n\n");
          scanf("%c", &addAnotherOption);
          _flushall();
            
          //Conditional if blocks to check to see if the course limit has been reached before allowing another course entry
          //If course limit has been reached, return user to main menu after brief warning / info message
          if(addAnotherOption == 'Y' || addAnotherOption == 'y')
          {
               if(position < 5)
               {
                     addCourse();      
               }
               else if(position >= 5)
               {  
                    //Show limit reached error
                    limitError();            
               }                                 
          }
          if(addAnotherOption == 'N' || addAnotherOption == 'n')
          {
               mainMenu();             
          }
    }//End addCourse()
    
    //Clean Input Data Before Saving Anywhere Function - (Deals with '/n' only at the moment)
    //Wouldn't let me pass both courseName & courseCode to strlen so had to make two instances of the check code
    void filterInput(Course courses[])
    {
         //CHECK courseCode VARIABLE FOR NEW LINE CHARACTER-----
         int x = strlen(courses[position].courseCode) -1;
         if(courses[position].courseCode[x] == '\n')
         {
            courses[position].courseCode[x] = '\0'; 
         }
         
         //CHECK courseName VARIABLE FOR NEW LINE CHARACTER-----
         x = strlen(courses[position].courseName) -1;
         if(courses[position].courseName[x] == '\n')
         {
            courses[position].courseName[x] = '\0'; 
         }           
    }
    
    //Read Data from file Function - Adapted from populate students example
    int readData(char fileName[], Course courses[], int position)
    {
        FILE *courseFile;
        
        courseFile = fopen(fileName, "rb");
        
        if (courseFile != NULL)
        {
              int i = -1;
    
              fread(&position, sizeof(int), 1, courseFile);
    
              while (i < position)
              {
              i++;
              fread(&courses[i], sizeof(Course), 1, courseFile);
              }
              fclose(courseFile);
        }
        return position;     
    }
    
    //parses the stored data for showing anywhere when called
    void parseData()
    {
        int i;
        if (position >= 0)
        {
           printf("Code\t Name\t\t Places\t Cost\n");
           printf("-------------------------------------\n");
           // repeats until all of the students' details have been displayed
           for (i = 0; i <= position -1; i++)
           {
               printf("%s\t%s\t%i\t%0.2f\n", courses[i].courseCode, 
                                             courses[i].courseName,
                                             courses[i].maxPlaces, 
                                             courses[i].courseCost);
           }
        } 
    }
    
    //Write Data to File Function
    void writeData(char fileName[], Course courses[], int position)
    {
       
        if(position >= 0)
        {
           FILE *courseFile = fopen(fileName, "wb");
           
           int i;
           
           fwrite(&position, sizeof(int), 1, courseFile);
           
           for(i = 0; i <= position; i++)
           {
              fwrite(&courses[i], sizeof(Course), 1, courseFile);  
           }
           fclose(courseFile);
        }
                 
    }
    
    
    
    void limitError()
    {
         system("cls");
         printf("---------------------------------------------------------------\n");
         printf("WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n");
         printf("---------------------------------------------------------------\n\n");
         printf("You Have Reached Your Trial Version Course Storage Limit.\n\n");
         printf("To unlock this program, please send me all your money!\n\n");
         printf("You will now be returned to the main menu\n\n");
         //Sleep tells the program to wait for a specified duration before proceeding
         sleep(8000);
         mainMenu();      
    }
    Last edited by DrC; 03-19-2011 at 01:44 PM.

  2. #2
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    You have the course code, fetched from stdin. You have the courses[] array initialized in your mainmenu function.

    Create a loop that iterates over all courses and let the terminating condition of the loop be a match of the course code. You can use the function strcmp() to do that. So in each iteration of the loop call: strcmp(courseCode[i], courses[i].courseCode) != 0. (strcmp() returns 0 on a match)

    You then know that 'i' is the index where your course is at. Now you can modify that struct and then write everything back to disk to update the file.

  3. #3
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void limitError()
    {
         system("cls");
         printf("---------------------------------------------------------------\n");
         printf("WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\n");
         printf("---------------------------------------------------------------\n\n");
         printf("You Have Reached Your Trial Version Course Storage Limit.\n\n");
         printf("To unlock this program, please send me all your money!\n\n");
         printf("You will now be returned to the main menu\n\n");
         //Sleep tells the program to wait for a specified duration before proceeding
         sleep(8000);
         mainMenu();      
    Since this function was called by mainMenu, you don't want to really do what you're doing here, you just want to let the function end, which will return to mainMenu. What you are doing is basically recursion with a pair of functions instead of just one:

    main calls error which calls main which calls error...

    Just let the function return normally without that last line, and you'll end up back in the function that called it.


    Quzah.
    Hope is the first step on the road to disappointment.

  4. #4
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Hi guys and thank you both for replying.

    @quzah:

    I have tried to remove the mainMenu() function call from the end of my limitError() function, however when limitError is now called, e.g. when I chose option 3 from the main menu to try and add another course and it detects that there are already 5 courses as it should do and after displaying the limitError message, it directs me to a system pause before terminating the program.

    @Subsonics:

    Thank you that will help me when I come to search for the string I'm after but I'm still a little puzzled about a few things.


    I will try and explain the situation as best I can....

    Basically, I've gone to college having gained no formal qualifications after leaving school.
    I went to learn to be a programmer after spending the years between leaving school and now learning and working with HTML, CSS and PHP which I enjoyed.

    However, the course I am on is 2 years rolled into one to fast track me to uni (GCSE and A level) and consequently, the education is being rammed down my throat faster than I can appreciate it or understand a lot of it.

    The college network is that slow and crappy I have to work from home and I recently got a telling off for my supposedly approved absenses and my sending email support questions so now I don't bother asking and so I'm pretty much on my own with 5 days left to finish the program and complete all associated documents such as structure chart, test plan, test log, evaluation etc etc.

    I really want to do this on my own, it's what I came to college to do but I'm finding it really hard when I don't understand a lot of it and to get this far, half of the code has been a mass of bodging example code together without really understanding what the hell I'm doing.

    Now I'm in a state where I just don't know what the hell is happening with my code; and I'm the one that wrote it.

    I know that sounds silly but I'm so stressed out right now.
    Time is not on my side and I feel really penned into a corner and so I'm working maybe 14 hours straight a day because I wont quit.

    What I don't get is when I'm modifying the data, do I need to load the data from file again into the modify function or is the data still floating about in the program from when I called the data in the first time using this peice of code:

    Code:
    position = readData(fileName, courses, position);
    and if so, where is it and how do I pass it on to my modify function?

    Then once I've modified the data I want, do I overwrite the whole file or just the string.
    Also when I search through the file, does it read lines of data or characters?
    How does it know which courseCost I want to modify in order to modify the data associated with the correct course?

    Sorry guys but I'm well confused

    The college examples I am working with aren't the best explained documents in the world leaving a lot of it is guess work and since I got told off for emailing support questions the only chances I get to ask questions are in class which doesn't help when working from home e.g. over the weekends.
    That then doesn't help because I don't know what I am googling for in terms of what the process are called I am trying to acheive and when I do find examples, they are hard to relate to what I'm doing without explanation.

    All told, I'm not finding this assignment as enjoyable as my last where I had the opportunity to understand the code being taught.
    I really feel in the dark on this one.
    Last edited by DrC; 03-20-2011 at 03:42 AM.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Redo your menu function with logic similar to this:
    Code:
    while choice is not quit
        show menu options
        get choice
        switch( choice )
            ... each choice
    Now say you're at "add", and you are already at your limit of five.
    Code:
    case ADD:
        if limit == 5
            print out an error
        else
            call your add function
    break;

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by DrC View Post
    What I don't get is when I'm modifying the data, do I need to load the data from file again into the modify function or is the data still floating about in the program from when I called the data in the first time using this peice of code:
    No you don't, you have an array called courses that is a global variable, it should be in memory since your menu function reads it in at initialization. BTW, looking at the code I supplied, I noticed a mistake, should be:

    Code:
    strcmp(courseCode, courses[i].courseCode) != 0)
    This should be your loop condition, you also need to add a condition for the max size of the array incase there is no match.

    This should all go after your fgets() call in modifyCourse. Create a loop, loop through all courses and in each iteration compare. It might be easier to use the strcmp with an if condition inside the loop, take appropriate action and break if a match is found.

  7. #7
    Registered User
    Join Date
    Jan 2011
    Posts
    5
    Woo Hoo!

    Thank you both so very very much!

    After a few painful hours of searching, refering back to this post and tweaking I've got it to do what I want

    It might not be the most streamlined and compliant code but it does what I need which was more the purpose of the exercise I guess.
    I'll worry about best pracitces when I'm not so under pressure, ie at Uni where they will be teaching us C programming over again duing the first year lol.

    My program now looks for the course with the data I want to modify by searching for a course code.
    The program then displays back the details of the selected course to the user to verify the correct course has been selected for modifying.

    Since I only want users to edit the course cost, I am able to modify just the course cost belonging to the course chosen before saving the file with the replaced data and it's all there intact as it was before except for the data that was changed.

    You guys really don't know how happy I am at this moment in time!!!

    Thank you, thank you and thank you again!
    Last edited by DrC; 03-20-2011 at 10:12 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Finding and replacing substrings
    By Raen in forum C Programming
    Replies: 1
    Last Post: 10-17-2010, 09:02 PM
  2. Replacing a substring with another
    By Dan17 in forum C Programming
    Replies: 3
    Last Post: 09-14-2006, 10:37 AM
  3. Replacing and finding chars in a string
    By xshapirox in forum C++ Programming
    Replies: 5
    Last Post: 10-11-2004, 11:40 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Question About Finding a Word and Replacing It
    By Zildjian in forum C Programming
    Replies: 3
    Last Post: 09-23-2003, 08:50 AM