need some help fixing issues in functions

Discussion in 'C++' started by mverwey, May 27, 2011.

  1. mverwey

    mverwey New Member

    Joined:
    May 27, 2011
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    **I don't know why, but when I posted this I lost the formatting for my code, so the loops are harder to identify where they start and stop.**

    I am currently working on an assignment for uni and have completed the majority of the coding myself, however the last few functions I have created aren't working the way I need them to. The questions for the functions I need help with are:

    When menu option 5. is selected, the program will allow you to delete one instance of the mark you want to delete, unless the mark doesn't exist.

    When menu option 6. is selected, the program will first read a mark from the user, and then search the available list of marks to see how many occurrences of this mark there are. It will then report this number of occurrences.

    When menu option 7. is selected, the program will go through all the distinctive marks in the list, and find out how many occurences there are for each of the distinctive marks. For instance, if the current list of marks contains.

    I will only post my code for the run menu function, and the functions that are not working as I want them to, unless anyone thinks that it may be another function that I have not coded properly.

    Code:
    int main()
    {
        runMenu();      //runs the entire menu.
        
        return 0;
    }
    
    void runMenu()
    {
        double mean = 0;
        int option;
        int totalRec = 0;
        double allMarks[totalRec];
        string word, msg = "Menu v1.0 13/05/2011\tMatthew Verwey-Cuthbert\t\t17232874";
        
        do
        {
               clrscr();
               displayMenu(msg);
               cin.clear();
               if(!(cin >> option))
               {
                       if(!cin.eof())
                       {
                                     cin.clear();
                                     cin >> word;
                                     }
                       continue;
                       }
               
               switch(option)
               {
                             case 1:
                                  addMark(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 2:
                                  displayMarks(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 3:
                                  findMean(allMarks, totalRec, mean);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 4:
                                  standardDev(allMarks, totalRec, mean);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 5:
                                  delMark(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 6:
                                  oneMarkOccur(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 7:
                                  allMarksOccur(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             default:
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                          
                                  }
                          }
               while (option);          
    }
    
    
    bool findMark(double allMarks[], int totalRec) //fix function
    {
         double mark;
         bool found = false;
         int first, last, middle;
         cout << "Mark to delete->";
         cin >> mark;
         
         first = 0;
         last = totalRec-1;
         
         while((first <= last) && !found)
         {
              middle = (first + last) / 2;
              if(allMarks[middle] == mark)
                   found = true;
              else if(mark > allMarks[middle])
                   first = middle + 1;
                 else
                   last = middle - 1;           
         }
         if(found)   return middle;
         else        return false;                
          
         pause();
    }
    
    bool delMark(double allMarks[], int &totalRec) //fix function
    {
         int middle = findMark(allMarks, totalRec);
         
         if(middle > 0)
         {
         cout << "\nThe mark " << allMarks[middle] << " has been removed." << endl;
                  for(int i = middle; i < totalRec; i++)
                  {
                    allMarks[i] = allMarks[i + 1];
                  }
         totalRec--;
         }
         else
             {
              cout << "\n**THE MARK YOU HAVE ENTERED WAS NOT FOUND**" << endl;
             }
         
         pause();
    }
    
    bool oneMarkOccur(double allMarks[], int totalRec)   //fix function
    {
         double mark = 0;
         int count = 0;
         
         cout << "Enter the mark to search for -> ";
         cin >> mark;
         
         for(int i = 0; i < totalRec; i++)
         {
                 allMarks[i];
                 
                 if(allMarks[i] = mark)
                       count++;
         }
         
         cout << "\nMARK\tOCCURENCE\n" 
              << "----\t---------\n"
              << mark << "\t" << count << endl;
         
         pause();
    }
    
    bool allMarksOccur(double allMarks[], int totalRec)
    {
         double temp;
         int count = 0;
         
         cout << "\nMARK\tOCCURENCE\n"
              << "----\t----------" << endl;
         
         for(int i = 0; i < totalRec; i++)
         {
                 temp = allMarks[i];
                 
                 for(int j = 0; j < totalRec; j++)
                 {
                         if(allMarks[j] = temp)
                            count++;
                         cout << temp << "\t" << count << endl;
                 }
         }
         
         pause();
    }
    
    Thank you in advance for any help/suggestions.
     
    Last edited by a moderator: May 27, 2011
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    In what way exactly are they not working as expected?
    What input did you give the program and what output did you get, and what output did you expect?

    Without any clues I can't see anything obviously wrong in the code, but hunting over code for a problem you don't know anything about (or even if it is a problem) is very difficult except in the most glaringly obvious mistakes.

    ......oh, hang on.....
    Code:
        int totalRec = 0;
        double allMarks[totalRec];
    
    Explain exactly what you think those two lines will do. How big will allMarks[] be?
    Do you think this is a variable size array that will be resized automatically when totalRec changes?
    (Are you a mathematician?)
     
  3. mverwey

    mverwey New Member

    Joined:
    May 27, 2011
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    Thanks for the reply.
    And sorry I completely forgot to explain what wasn't working.

    When I enter say these 4 numbers into the array: 41, 42, 43, 44, 45 and then try to delete for instance 44, it will delete the element at allMarks[1] every time. Also if I try to delete the element allMarks[0] it will display the message "the entered mark could not be found" although I know that it is in the array.

    When I try to find the occurrence of one mark, the loop counts all of the elements in the array, instead of the entered mark.

    When I search for all marks and their occurrences it will display the mark as the element saved in allMarks[1] and the occurrence will be all the totalRec of the array.

    As for the part of the code that you suspect to be wrong, this is where it works
    Code:
    bool addMark(double allMarks[], int &totalRec)
    {
         cout << "Add a student mark -> ";
         cin >> allMarks[totalRec];
         cout << "\n\n** A new mark " << allMarks[totalRec] << " was added." << endl;
         totalRec++;
         pause();
    }
     
  4. mverwey

    mverwey New Member

    Joined:
    May 27, 2011
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    I think that this is the issue with my code, however when I change the size of the array to totalRec = 1000, I cannot modify other parts of the code to compensate for it.

    Is it possible for some hints or help as to how I can change the code to fix these issues?

    thanks.

    complete code here
    Code:
    
    #include <iostream>
    #include <cmath>
    using namespace std;
    
    //function prototypes.
    void clrscr();
    void pause();
    void runMenu();
    void displayMenu(string msg);
    bool addMark(double allMarks[], int &totalRec);
    bool sortMarks(double allMarks[], int totalRec);
    bool displayMarks(double allMarks[], int totalRec);
    bool findMean(double allMarks[], int totalRec, double &mean);
    bool standardDev(double allMarks[], int totalRec, double &mean);
    bool findMark(double allMarks[], int totalRec);
    bool delMark(double allMarks[], int &totalRec);
    bool oneMarkOccur(double allMarks[], int totalRec);
    bool allMarksOccur(double allMarks[], int totalRec);
    
    int main()
    {
        runMenu();      //runs the entire menu.
        
        return 0;
    }
    
    void runMenu()
    {
        double mean = 0;
        int option;
        int totalRec = 1000;
        double allMarks[totalRec];
        string word, msg = "Menu v1.0 13/05/2011\tMatthew Verwey-Cuthbert\t\t17232874";
        
        do
        {
               clrscr();
               displayMenu(msg);
               cin.clear();
               if(!(cin >> option))
               {
                       if(!cin.eof())
                       {
                                     cin.clear();
                                     cin >> word;
                                     }
                       continue;
                       }
               
               switch(option)
               {
                             case 1:
                                  addMark(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 2:
                                  displayMarks(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 3:
                                  findMean(allMarks, totalRec, mean);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 4:
                                  standardDev(allMarks, totalRec, mean);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 5:
                                  delMark(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 6:
                                  oneMarkOccur(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             case 7:
                                  allMarksOccur(allMarks, totalRec);
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                             default:
                                  msg = '0' + option;
                                  msg += " was last selected";
                                  break;
                          
                                  }
                          }
               while (option);          
    }
    
    void clrscr()
    {
         system("cls");
    }
         
    void pause()
    {
         system("echo.");
         system("echo.");
         system("pause");
    }
         
    void displayMenu(string msg)
    {
         clrscr();
         cout << msg << "\n\nMAIN MENU\
                 \n0. Exit\
                 \n1. Add a student mark\
                 \n2. List all student marks\
                 \n3. Calculate the marks average\
                 \n4. Calculate the standard deviation\
                 \n5. Delete a student mark\
                 \n6. Find the number of students via a mark\
                 \n7. Display distinct marks and their occurences\
                 \n\nYour choice ->";
    }
                 
    
    bool addMark(double allMarks[], int &totalRec)
    {
         cout << "Add a student mark -> ";
         cin >> allMarks[totalRec];
         cout << "\n\n** A new mark " << allMarks[totalRec] << " was added." << endl;
         totalRec++;
         pause();
    }
    
    bool sortMarks(double allMarks[], int totalRec)
    {
         int i, j, minidx; 
         double min, temp;
         
         for(i = 0; i < (totalRec-1); i++)
         {
               min = allMarks[i];     //assume minimum is the first array element.
               minidx = i;            //index of minimum element.
               for(j = i + 1; j < totalRec; j++)
               {
                     if (allMarks[j] < min)      // if we've located a lower value.
                     {                           // capture it.
                       min = allMarks[j];
                       minidx = j;
                     }
               }
               if (min < allMarks[i])            // check if we have a new minimum.
               {                                 //if we do, swap values.
                 temp = allMarks[i];
                 allMarks[i] = min;
                 allMarks[minidx] = temp;
                 }
         }
    }
         
    bool displayMarks(double allMarks[], int totalRec)
    {
         sortMarks(allMarks, totalRec);
         
         cout << "ALL STUDENT MARKS:" << endl;
         for (int i=0; i < totalRec; i++)
             cout << allMarks[i] << "\t";  
             pause();   
    }
    
    bool findMean(double allMarks[], int totalRec, double &mean)
    {
         double total;
         for (int i = 0; i < totalRec; i++)
         {
             total += allMarks[i];
             }
         mean = total / totalRec;
         
         cout << "The average of all entered makrs is: " << mean << endl;
         pause();
    }
    
    bool standardDev(double allMarks[], int totalRec, double &mean)
    {
         double total;
         for (int i = 0; i < totalRec; i++)
         {
             total += allMarks[i];
             }
         mean = total / totalRec;      //Re-calculates mean in case the user has not
                                       //used option 3 to find the average yet.
         
         double standardDev = 0;       //Holds the standard deviation.
         for(int i = 0; i < totalRec; i++)  
         {
                  standardDev += (allMarks[i] - mean) * (allMarks[i] - mean);
                  //Calculates the total of all (value - mean) of the array.
                  }
         standardDev = standardDev/totalRec;    //Divides the total from above by 
                                                //the total number of values in the array.
                                                
         standardDev = sqrt(standardDev);       //Finds the square root of the value
                                                //found above
         
         cout << "The standard deviation of all of the entered marks is: "
              << standardDev << endl;
         
         pause();
    }
    
    bool findMark(double allMarks[], int totalRec) //fix function
    {
         double mark;
         bool found = false;
         int first, last, middle;
         cout << "Mark to delete->";
         cin >> mark;
         
         first = 0;
         last = totalRec-1;
         
         while((first <= last) && !found)
         {
              middle = (first + last) / 2;
              if(allMarks[middle] == mark)
                   found = true;
              else if(mark > allMarks[middle])
                   first = middle + 1;
                 else
                   last = middle - 1;           
         }
         if(found)   return middle;
         else        return false;                
          
         pause();
    }
    
    bool delMark(double allMarks[], int &totalRec) //fix function
    {
         int middle = findMark(allMarks, totalRec);
         
         if(middle > 0)
         {
         cout << "\nThe mark " << allMarks[middle] << " has been removed." << endl;
                  for(int i = middle; i < totalRec; i++)
                  {
                    allMarks[i] = allMarks[i + 1];
                  }
         totalRec--;
         }
         else
             {
              cout << "\n**THE MARK YOU HAVE ENTERED WAS NOT FOUND**" << endl;
             }
         
         pause();
    }
    
    bool oneMarkOccur(double allMarks[], int totalRec)   //fix function
    {
         double mark = 0;
         int count = 0;
         
         cout << "Enter the mark to search for -> ";
         cin >> mark;
         
         for(int i = 0; i < totalRec; i++)
         {
                 allMarks[i];
                 
                 if(allMarks[i] = mark)
                       count++;
         }
         
         cout << "\nMARK\tOCCURENCE\n" 
              << "----\t---------\n"
              << mark << "\t" << count << endl;
         
         pause();
    }
    
    bool allMarksOccur(double allMarks[], int totalRec)
    {
         double temp;
         int count = 0;
         
         cout << "\nMARK\tOCCURENCE\n"
              << "----\t----------" << endl;
         
         for(int i = 0; i < totalRec; i++)
         {
                 temp = allMarks[i];
                 
                 for(int j = 0; j < totalRec; j++)
                 {
                         if(allMarks[j] = temp)
                            count++;
                         cout << temp << "\t" << count << endl;
                 }
         }
         
         pause();
    }
    
     
  5. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    allMarks should be the largest size possible. If you want to store less than 1000 entries, this will do the trick:
    Code:
    double allMarks[1000];
    
    Based on the usage I'd say you need to initialise totalRec to zero.

    Your findMean defines a local variable total but doesn't give it an initial value. So the computation is meaningless (if your compiler didn't throw a warning here, get a new compiler. Or switch warnings on). You repeat this error in another function; see if you can find it.

    delMark problem, OK I get the same. [1] is deleted regardless. Let's try adding some debug:
    Code:
    bool delMark(double allMarks[], int &totalRec) //fix function
    {
         int middle = findMark(allMarks, totalRec);
    printf("delMark: middle=%d\n",middle);
    
         if(middle > 0)
    
    The output I get is this:

    Your choice ->5
    Mark to delete->44
    delMark: middle=1

    The mark 42 has been removed.

    That should give you some idea of (a) where to look for the problem and (b) how to look for the problem. Try it and see if you can find the problem.

    Your find function seems a bit overcomplicated. Have you been explicitly told not to just do a for loop over the whole array? If so you could do that while you get everything else working then optimise the search later on.
     
    shabbir likes this.
  6. mverwey

    mverwey New Member

    Joined:
    May 27, 2011
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    Thanks for your reply. I have recently fixed all of my functions except for the last one, which I should have done by tomorrow.

    The function where I search for the mark to delete is a binary search, hence the function to arrange the marks, however I was told yesterday that I can simply remove these two and do a linear search as that is all that is expected from me. However I am considering keeping these two as they are working fine for me with the compiler that I have to year.

    It turns out I only had to tweak 1 small part of each of the functions to actually get them to work as expected.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice