Thread: Some bugs which i can't find

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    17

    Question Some bugs which i can't find

    The following lines of codes are supposed to run smoothly without any error. However, after I debug for minutes, I got tired. I don't see any errors in my scripts. Can someone help me out? Its supposed to be a grades calculation program.

    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
        //declaring english students fixed percentage of marks
        const float ENGLISH_MIDTERM_PERCENTAGE = 0.25;
        const float ENGLISH_FINALEXAM_PERCENTAGE = 0.25;
        const float ENGLISH_RESEARCH_PERCENTAGE = 0.30;
        const float ENGLISH_PRESENTATION_PERCENTAGE = 0.20; //end of english students fixed percentage
        
        //declaring maths students fixed percentage of marks
        const float MATH_MIDTERM_PERCENTAGE = 0.50;
        const float MATH_FINALEXAM_PERCENTAGE = 0.50; //end of math students fixed percentage
        
        //declaring science students fixed percentage of marks
        const float SCIENCE_MIDTERM_PERCENTAGE = 0.40;
        const float SCIENCE_FINALEXAM_PERCENTAGE = 0.40;
        const float SCIENCE_RESEARCH_PERCENTAGE = 0.20; //end of science students fixed percentage
        
        //declaring variables 
        short midterm = 0;
        short finalExamGrade = 0;
        short research = 0;
        short presentation = 0;
        float finalNumericGrade = 0;
        char finalLetterGrade;
        char response[256];
        string moreGradesToCalculate;
        //end of variables declaration
        
        //prompt user "whether they want to calculate grades"
        cout<< "Do you want to calculate a grade? Yes/No ";
        cin>> moreGradesToCalculate;
        
        //start of for loop for changing userinput to uppercase
        for (unsigned short a = 0; a < moreGradesToCalculate.length(); a++)
        {
            moreGradesToCalculate[a] = toupper (moreGradesToCalculate[a]);
        }
        //end of for loop 
        //end of promting user
        
        
        //start of while loop 
        while (moreGradesToCalculate == "YES")
        {
              //promting user for the type of students to calculate
              cout<< "*** 1) English, 2) Math, 3) Science *** ";
              cin.getline (response, 256);
              
              if (strlen(response) == 0)
              { 
                   cout<< "You must choose an option";
                   return 1; //return error
              }
              
              else if ((atoi(response) < 1) || (atoi(response) > 3))
              {
                   cout<< " - is not a valid option.";
                   return 1;
              }
              
              //After user had input a valid student type, the following is to calculate the student's grade
              //start of switch statement
              switch (atoi(response))
              {
                     //case 1 is english student
                     case 1: 
                          //Promt user for "midterm" grade
                          cout<< "Please enter the Midterm Grade: ";
                          cin.getline (response,256);
                          midterm = atoi(response);
                          //end of "midterm" grade
                          
                          //Promt user for "finalExamGrade"
                          cout<< "Please enter the Final Examination Grade: ";
                          cin.getline (response,256);
                          finalExamGrade = atoi(response);
                          //end of "finalExamGrade"
                          
                          //promt user for "research" grade
                          cout<< "Please enter the research Grade: ";
                          cin.getline (response,256);
                          research = atoi(response);
                          //end of "research"
                          
                          //Prompt user for "presentation" grade
                          cout<< "Please enter the Presentation Grade: ";
                          cin.getline (response,256);
                          presentation = atoi(response);
                          //end of "presentation"
                          
                          finalNumericGrade = (midterm * ENGLISH_MIDTERM_PERCENTAGE) + 
                                              (finalExamGrade * ENGLISH_FINALEXAM_PERCENTAGE) +
                                              (research * ENGLISH_RESEARCH_PERCENTAGE) +
                                              (presentation * ENGLISH_PRESENTATION_PERCENTAGE);
                                              
                          if (finalNumericGrade >= 93)
                          {
                               finalLetterGrade = 'A';
                          }
                          
                          else if ((finalNumericGrade >=85) && (finalNumericGrade < 93))
                          {
                               finalLetterGrade = 'B';
                          }
                          
                          else if ((finalNumericGrade >= 78) && (finalNumericGrade < 85))
                          {
                               finalLetterGrade = 'C';
                          }
                          
                          else if ((finalNumericGrade >= 70) && (finalNumericGrade < 78))
                          {
                               finalNumericGrade = 'D';
                          }
                          
                          else if (finalNumericGrade < 70)
                          {
                               finalNumericGrade = 'F';
                          }
                          
                          //display student scores' informations
                          cout<< "*** ENGLISH STUDENT ***" <<endl <<endl;
                          cout<< "Midterm Grade is "<< midterm<< endl;
                          cout<< "Final Exame is: "<< finalExamGrade<< endl;
                          cout<< "Research is: "<< research<< endl;
                          cout<< "Presentation is: "<< presentation<< endl<< endl;     
                          cout<< "Final Numeric Grade is: "<< finalNumericGrade<< endl;
                          cout<< "Finak Letter Grade is: "<< finalLetterGrade;
                          
                          break;
                          //end of english student
                          
                          
                          //case 2 is a math student
                          case 2:
                               
                               //Prompt user for "midterm" grade
                               cout<< "Enter the Midterm Grade: ";
                               cin.getline(response,256);
                               midterm = atoi(response);
                               //end of "midterm" grade
                               
                               //Promt user for "finalExamGrade"
                               cout<< "Enter the Final Examination Grade: ";
                               cin.getline(response,256);
                               finalExamGrade = atoi(response);
                               //end of "finalExamGrade"
                               
                               finalNumericGrade = (midterm * MATH_MIDTERM_PERCENTAGE) + 
                                              (finalExamGrade * MATH_FINALEXAM_PERCENTAGE);
                                              
                               if (finalNumericGrade >= 90)
                               {
                                    finalLetterGrade = 'A';
                               }
                          
                               else if ((finalNumericGrade >= 83) && (finalNumericGrade < 90))
                               {
                                    finalLetterGrade = 'B';
                               }
                          
                               else if ((finalNumericGrade >= 76) && (finalNumericGrade < 83))
                               {
                                    finalLetterGrade = 'C';
                               }
                          
                               else if ((finalNumericGrade >= 65) && (finalNumericGrade < 76))
                               {
                                    finalNumericGrade = 'D';
                               }
                          
                               else if (finalNumericGrade < 65)
                               {
                                    finalNumericGrade = 'F';
                               }
                               
                               //display student scores' informations
                               cout<< "*** MATH STUDENT ***" <<endl <<endl;
                               cout<< "Midterm Grade is "<< midterm<< endl;
                               cout<< "Final Exame is: "<< finalExamGrade<< endl;
                               cout<< "Research is: "<< research<< endl;
                               cout<< "Presentation is: "<< presentation<< endl<< endl;     
                               cout<< "Final Numeric Grade is: "<< finalNumericGrade<< endl;
                               cout<< "Finak Letter Grade is: "<< finalLetterGrade;
                               
                               break;                        
                               //end of math student
                               
                               
                               //case 3 is a Science student
                               case 3:
                                    
                                    //Prompt user for "midterm" grade
                                    cout<< "Enter the Midterm Grade: ";
                                    cin.getline(response,256);
                                    midterm = atoi(response);
                                    //end of "midterm" grade
                               
                                    //Promt user for "finalExamGrade"
                                    cout<< "Enter the Final Examination Grade: ";
                                    cin.getline(response,256);
                                    finalExamGrade = atoi(response);
                                    //end of "finalExamGrade"
                                     
                                    //Prompt user for "research" grade
                                    cout<< "Enter the Research Grade: ";
                                    cin.getline(response, 256);
                                    research = atoi(response);
                                    //end of "research"
                                    
                                    finalNumericGrade = (midterm * SCIENCE_MIDTERM_PERCENTAGE) + 
                                              (finalExamGrade * SCIENCE_FINALEXAM_PERCENTAGE) +
                                              (research * SCIENCE_RESEARCH_PERCENTAGE);
                                    
                                    if (finalNumericGrade >= 90)
                                    {
                                         finalLetterGrade = 'A';
                                    }
                          
                                    else if ((finalNumericGrade >= 80) && (finalNumericGrade < 90))
                                    {
                                         finalLetterGrade = 'B';
                                    }
                          
                                    else if ((finalNumericGrade >= 70) && (finalNumericGrade < 80))
                                    {
                                         finalLetterGrade = 'C';
                                    }
                               
                                    else if ((finalNumericGrade >= 60) && (finalNumericGrade < 70))
                                    {
                                         finalNumericGrade = 'D';
                                    }
                          
                                    else if (finalNumericGrade < 60)
                                    {
                                         finalNumericGrade = 'F';
                                    }
                                    
                                    //display student scores' informations
                                    cout<< "*** SCIENCE STUDENT ***" <<endl <<endl;
                                    cout<< "Midterm Grade is "<< midterm<< endl;
                                    cout<< "Final Exame is: "<< finalExamGrade<< endl;
                                    cout<< "Research is: "<< research<< endl;
                                    cout<< "Presentation is: "<< presentation<< endl<< endl;     
                                    cout<< "Final Numeric Grade is: "<< finalNumericGrade<< endl;
                                    cout<< "Finak Letter Grade is: "<< finalLetterGrade;
                               
                                    break;                        
                                    //end of science student
                                    
                                    //start of default for the switch statement
                                    default:
                                            cout<< response<< " - is not a valid student type";
                                            return 1;
                                    } 
                                    //end of switch statement
                                    
                                    cout<< endl<< endl<< "Do you have another grade to calculate? Yes/No ";
                                    cin>> moreGradesToCalculate;
                                    
                                    //start of for loop
                                    for (unsigned short a = 0; a < moreGradesToCalculate.length(); a++)
                                    {
                                        moreGradesToCalculate[a] = toupper (moreGradesToCalculate[a]);
                                    }
                                    //end of for loop
                                    }
                                    //end of while loop
                                    
                                    cout<< "Thanks for using the Grades Calculation program! ";
                                    
                                    return 0;
                                    }
                                    //end of main

    It seems that this part of codes here has the error:

    Code:
    //start of while loop 
        while (moreGradesToCalculate == "YES")
        {
              //promting user for the type of students to calculate
              cout<< "*** 1) English, 2) Math, 3) Science *** ";
              cin.getline (response, 256);
              
              if (strlen(response) == 0)
              { 
                   cout<< "You must choose an option";
                   return 1; //return error
              }
    Thanks in advance!

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Could you describe in more detail what the error you're getting is? What input do you give it?

    If I had to guess at the problem, I'd say it's that you're mixing cin >> with getline. When you use cin >> to read in something (like moreGradesToCalculate), the user types an answer and hits enter. That enter puts a newline character in the stream, but cin >> doesn't read the newline, it leaves it there. Later, when you call getline, that function stops at the first newline it finds. Since there is a leftover newline from the previous call to cin >> moreGradesToCalculate, it stops immediately and the response variable is left empty. That causes the first error check to be met and the program to return 1 immediately.

    The simple solution is to add cin.ignore() after any and every call to cin >>. This ignores the trailing newline. Do not add cin.ignore() after calls to getline, because getline automatically ignores the trailing newline.

    You can also do more advanced input error handling, but assuming valid input by the user the solution above should work well.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Quote Originally Posted by Lincoln_Poh View Post
    The following lines of codes are supposed to run smoothly without any error.
    is that a new design paradigm?

    However, after I debug for minutes, I got tired.
    minutes!? way too long!

    I don't see any errors in my scripts. Can someone help me out?
    its kind of hard to look for something, if we dont know what we're looking for (also a C++ program isnt a "script"). so what "bug" or "error" are we looking for? is there a runtime _error_, such as a pointer problem, or is it a bug such as output should be "5" but it is "10". what is happening, and what is supposed to be happening.

  4. #4
    Registered User
    Join Date
    Sep 2008
    Posts
    17
    Quote Originally Posted by Daved View Post
    Could you describe in more detail what the error you're getting is? What input do you give it?

    If I had to guess at the problem, I'd say it's that you're mixing cin >> with getline. When you use cin >> to read in something (like moreGradesToCalculate), the user types an answer and hits enter. That enter puts a newline character in the stream, but cin >> doesn't read the newline, it leaves it there. Later, when you call getline, that function stops at the first newline it finds. Since there is a leftover newline from the previous call to cin >> moreGradesToCalculate, it stops immediately and the response variable is left empty. That causes the first error check to be met and the program to return 1 immediately.

    The simple solution is to add cin.ignore() after any and every call to cin >>. This ignores the trailing newline. Do not add cin.ignore() after calls to getline, because getline automatically ignores the trailing newline.

    You can also do more advanced input error handling, but assuming valid input by the user the solution above should work well.

    Holy >.< I don't understand a word you're saying. Im not that pro. Im just a noob. I don't really understand those terms so well.

    Basically, the error is that when i build it, it runs and ask me whether if i want to calculate a student's grade. Lets assume I type in yes. Because of the toupper function, it capitalize the yes into "YES". Then the while loop returns a true condition. Then it starts to execute the while loop.

    It ask for the type of student which Im calculating for (English, Math or Science student). Then, without giving any option for me to press, it straight away tells me that I have to choose an option.

    This is the error Im getting...

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    well, as Daved said:
    The simple solution is to add cin.ignore() after any and every call to cin >>. This ignores the trailing newline. Do not add cin.ignore() after calls to getline, because getline automatically ignores the trailing newline.
    looks like hes right again, too! and as he said, that is the simple solution so you can just go ahead and do what he suggested. im sure he will try and explain further the weird terms, etc. please just try and reread all of what he said, repeatedly and slowly--thats the only way anyone can really learn to understand something. the terms and ideas he is using is actually not that complicated or difficult to understand. hes basically explaining what your doing, so should be able to understand it.
    Last edited by nadroj; 09-17-2008 at 10:33 PM.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> I don't understand a word you're saying. Im not that pro.

    A "newline" is just a character that indicates that a new line should start. It is usually denoted as '\n'.

    cin.ignore() is just a function. You call it like this:
    Code:
    cin.ignore();
    It ignores a character in cin. In this case you will use it to ignore the newline character.

    The stream is what we call the place where the user input is stored. The user types something and hits enter. The characters the user types are placed in the input stream. You use cin to read from the input stream.

    When you call cin >> moreGradesToCalculate; the program tries to read from the input stream. It is empty at first, so it waits for the user to type something. If the user types 'y' 'e' 's' <enter>, then the input stream will be filled with the following characters: 'y', 'e', 's', '\n'.

    The <enter> tells cin to go ahead and try to read the input stream again. This time there are characters there, so the program reads until it finds a space or a newline character (or tab character). In this case it reads 'y', 'e', and 's' and stops at the newline character '\n'. It leaves the '\n' in the input stream for later.

    So further down in your code, you call cin.getline (response, 256);. Again, it checks the input stream for characters. It finds the leftover '\n' from the previous time. The point of getline is to read until it sees a '\n' character, so it has everything it needs and stops immediately. It doesn't allow the user to type anything. Instead it just fills the response string with all the characters it read before it found the '\n'. In this case there were none, so response will be empty.

    Then your code checks the length of response, which is 0, and it errors out.

    By adding the cin.ignore(); function after cin >> moreGradesToCalculate; you tell cin to read a single character from the input stream and ignore it. In this case, it reads that leftover newline character. So later when you call cin.getline (response, 256); the input stream will be empty. cin will then wait for the user to type in something and hit enter and your code will function as you expect it to.

    Does that make sense? It is a very common problem that can be confusing for new users. While you should try to understand my explanation, it is not essential at this point of your learning. At the very least you should be able to implement the fix even without understanding it.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Btw, a word of advice:
    It's better to do:

    std::string response;
    std::getline(response);

    Instead of

    char response[256];
    cin.getline(response, 256);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Sep 2008
    Posts
    17

    Wink

    Quote Originally Posted by Daved View Post
    >> I don't understand a word you're saying. Im not that pro.

    A "newline" is just a character that indicates that a new line should start. It is usually denoted as '\n'.

    cin.ignore() is just a function. You call it like this:
    Code:
    cin.ignore();
    It ignores a character in cin. In this case you will use it to ignore the newline character.

    The stream is what we call the place where the user input is stored. The user types something and hits enter. The characters the user types are placed in the input stream. You use cin to read from the input stream.

    When you call cin >> moreGradesToCalculate; the program tries to read from the input stream. It is empty at first, so it waits for the user to type something. If the user types 'y' 'e' 's' <enter>, then the input stream will be filled with the following characters: 'y', 'e', 's', '\n'.

    The <enter> tells cin to go ahead and try to read the input stream again. This time there are characters there, so the program reads until it finds a space or a newline character (or tab character). In this case it reads 'y', 'e', and 's' and stops at the newline character '\n'. It leaves the '\n' in the input stream for later.

    So further down in your code, you call cin.getline (response, 256);. Again, it checks the input stream for characters. It finds the leftover '\n' from the previous time. The point of getline is to read until it sees a '\n' character, so it has everything it needs and stops immediately. It doesn't allow the user to type anything. Instead it just fills the response string with all the characters it read before it found the '\n'. In this case there were none, so response will be empty.

    Then your code checks the length of response, which is 0, and it errors out.

    By adding the cin.ignore(); function after cin >> moreGradesToCalculate; you tell cin to read a single character from the input stream and ignore it. In this case, it reads that leftover newline character. So later when you call cin.getline (response, 256); the input stream will be empty. cin will then wait for the user to type in something and hit enter and your code will function as you expect it to.

    Does that make sense? It is a very common problem that can be confusing for new users. While you should try to understand my explanation, it is not essential at this point of your learning. At the very least you should be able to implement the fix even without understanding it.
    OMG! After reading slowly and absorbing what Daved replied, Im really surprised I understand it! THANKS DAVED! You're the best

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. please help!...find and replace
    By amy589 in forum C++ Programming
    Replies: 26
    Last Post: 10-13-2006, 06:42 PM
  2. Can't find DirectX!!!
    By Queatrix in forum C++ Programming
    Replies: 2
    Last Post: 07-24-2006, 07:50 PM
  3. Replies: 3
    Last Post: 06-09-2006, 09:53 AM
  4. Q: Recursion to find all paths of a maze
    By reti in forum C Programming
    Replies: 7
    Last Post: 11-26-2002, 09:28 AM
  5. RE: Find out running processes from command prompt
    By sampatel in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 10-18-2001, 07:15 AM