Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C/++/# Flushing Data in Loop? -- Keep Entering Empty Space

  1. Nov 19, 2016 #1
    Hello,

    I am in my first class for C++, so I apologize in advance if this question is amateurish. To be clear, this project is already finished, and what I am trying to do already counted points off against me; I am not interested in cheating, I just want to know what the answer to my issue is.

    My code is below surrounded by ---'s (there is a part asking for a text file involved only in the project, please ignore). The issue is under the "if (menuOptionStrInt == "1"){" segment.

    Effectively, this part of the code is meant to prompt the user to enter their information and to enter an amount of cell phone minutes used. The program then returns the amount owed per cell minutes used, which the user is asked to pay in pennies (e.g., if $10.00 is owed, and you wanted to pay off the full amount: when prompted, you would enter 1000 to represent the amount of pennies paid). You may enter an insufficient amount; however, the program simply returns you to the main menu with a simple error message in this case.

    My problem is that, when I go through menu option 1, no matter what I do, once I reach the end, the program returns to the main menu, enters a blank space, then returns to the menu again (resulting in two main menu screens with no options entered). Constructively, this does not cause any issues, as it eventually returns the user to the main menu where you should be returned to anyway. I just do not know why it is doing this, or how to prevent it. My suspicion, based on a few quick web searches, is that my program does not flush the data entry made for "minutesUsed" (it collects the "enter" if I understand this correctly?).

    Thank you so much in advance. Feel free to tell me that I need to reformat this differently for ease of reference.

    Here is the code:

    ---------------------------------------------------------------------------------------------------------------------------------

    #include <iostream>
    #include <iomanip>
    #include <cstring>
    #include <cmath>
    #include <fstream>

    using namespace std;

    int main(){
    //Set main variables
    string customerName, address, city, state, zip, menuOptionStrInt, menuOptionStrChar;
    int minutesUsed, amountOwedInteger, customerAmount, changeDollars, changeQuarters, changeDimes, changeNickels, changePennies, i;
    double amountOwed;
    const double PER_MINUTES_CONSTANT = 0.20, BASE_CHARGE_CONSTANT = 10.00;
    ifstream inputfile;
    //begin the do/while loop to keep the user in the program unless they select to quit
    do{
    //prompt the user with a menu presenting the options
    cout << endl << "Welcome to the Cellular Telephone System" << endl;
    cout << endl;
    cout << "1 - Process Telephone Bill" << endl;
    cout << "2 - Translate Phone Word" << endl;
    cout << "3 - Process a Data File" << endl;
    cout << "4 - Quit" << endl;
    cout << endl;
    cout << "Enter your choice: ";
    getline(cin, menuOptionStrInt);
    cout << endl;
    //begin the options from the menu. The first is for the customer to enter data
    if (menuOptionStrInt == "1"){
    cout << "Enter the name of the customer: ";
    getline(cin, customerName);
    cout << "Enter street address: ";
    getline(cin, address);
    cout << "Enter city: ";
    getline(cin, city);
    cout << "Enter state: ";
    getline(cin, state);
    cout << "Enter zip code: ";
    getline(cin, zip);
    cout << "Enter the number of minutes used: ";
    cin >> minutesUsed;
    cout << endl;
    //Calculate the amount owed
    if (minutesUsed <= 50){
    amountOwed = BASE_CHARGE_CONSTANT;
    }
    else{
    amountOwed = ((minutesUsed - 50) * PER_MINUTES_CONSTANT) + BASE_CHARGE_CONSTANT;
    }
    //Return all of the previously entered information and the amount owed
    cout << endl;
    cout << customerName << endl;
    cout << address << endl;
    cout << city << ", " << state << " " << zip << endl;
    cout << "Amount Owed: $" << setprecision(2) << fixed << amountOwed << endl;
    //Prompt the user to enter the amount received from the customer in pennies
    cout << endl;
    cout << "Enter the amount received from the customer: ";
    cin >> customerAmount;
    cout << endl;
    //Calculate the variables for change
    amountOwedInteger = amountOwed * 100;

    if (customerAmount < amountOwedInteger){
    cout << "The amount paid is not enough to cover the cost of the bill." << endl;
    cout << "You must pay " << amountOwedInteger - customerAmount << " more pennies to pay off the bill." << endl;
    }
    else{
    customerAmount = customerAmount - amountOwedInteger;
    changeDollars = customerAmount/100;
    customerAmount %= 100;
    changeQuarters = customerAmount/25;
    customerAmount %= 25;
    changeDimes = customerAmount/10;
    customerAmount %= 10;
    changeNickels = customerAmount/5;
    customerAmount %= 5;
    changePennies = customerAmount;
    //Output the change in a formatted table
    cout << endl;
    cout << "Denomination" << setw(11) << "Number" << endl;
    cout << "----------" << setw(15) << "----------" << endl;
    cout << "Dollars " << setw(12) << changeDollars << endl;
    cout << "Quarters " << setw(11) << changeQuarters << endl;
    cout << "Dimes " << setw(14) << changeDimes << endl;
    cout << "Nickels " << setw(12) << changeNickels << endl;
    cout << "Pennies " << setw(12) << changePennies << endl;
    }
    }
    else if (menuOptionStrInt == "2"){
    cout << "Enter the phone word: ";
    getline(cin, menuOptionStrChar);
    if (menuOptionStrChar.length() != 8){
    cout << endl << "You must enter a value in the following format\n\n`XXX-XXXX`\n\nwhere `X` is a letter and the `-`\nis a simple dash." << endl;
    continue;
    }
    else if (menuOptionStrChar.at(3) != '-'){
    cout << endl << "You must enter a value in the following format\n\n`XXX-XXXX`\n\nwhere `X` is a letter and the`-`\nis a simple dash." << endl;
    continue;
    }
    cout << endl << menuOptionStrChar << " translates to ";
    for(i = 0; i < menuOptionStrChar.length(); i++){
    int number;
    if ((menuOptionStrChar.at(i) >= 'A' && menuOptionStrChar.at(i) <= 'Z') || (menuOptionStrChar.at(i) >= 'a' && menuOptionStrChar.at(i) <= 'z') || (menuOptionStrChar.at(i) == '-')){
    switch (menuOptionStrChar.at(i)){
    case '-':
    cout << "-";
    continue;
    break;

    case 'A':
    case 'a':
    case 'B':
    case 'b':
    case 'C':
    case 'c':
    number = 2;
    break;

    case 'D':
    case 'd':
    case 'E':
    case 'e':
    case 'F':
    case 'f':
    number = 3;
    break;

    case 'G':
    case 'g':
    case 'H':
    case 'h':
    case 'I':
    case 'i':
    number = 4;
    break;

    case 'J':
    case 'j':
    case 'K':
    case 'k':
    case 'L':
    case 'l':
    number = 5;
    break;

    case 'M':
    case 'm':
    case 'N':
    case 'n':
    case 'O':
    case 'o':
    number = 6;
    break;

    case 'P':
    case 'p':
    case 'Q':
    case 'q':
    case 'R':
    case 'r':
    case 'S':
    case 's':
    number = 7;
    break;

    case 'T':
    case 't':
    case 'U':
    case 'u':
    case 'V':
    case 'v':
    number = 8;
    break;

    case 'W':
    case 'w':
    case 'X':
    case 'x':
    case 'Y':
    case 'y':
    case 'Z':
    case 'z':
    number = 9;
    break;
    }
    cout << number;
    }
    //This line spits out a '*' whenever a non valid, but correctly formatted, letter is entered
    else{
    cout << "*";
    }
    }
    cout << endl;
    }
    //option 3 is for reading a data file containing information from option 1
    else if (menuOptionStrInt == "3"){
    //string variable for spitting out data
    string customerData;
    double numberData;
    //open file
    inputfile.open("TelephoneData.txt");
    //create loop to read data per entry based on the expected format
    while ((inputfile >> customerData) || (inputfile >> numberData)){
    //first name output
    cout << customerData;
    //move to last name
    inputfile >> customerData;
    //space and the last name output and endline
    cout << " " << customerData << endl;
    //move to numeric part of address
    inputfile >> customerData;
    //output numeric part of address and add space
    cout << customerData;
    //grab text part of address
    getline(inputfile, customerData);
    //output text part of address and end line
    cout << customerData << endl;
    //collect city
    inputfile >> customerData;
    //out put city with no space, but add comma
    cout << customerData << ", ";
    //collect state
    inputfile >> customerData;
    //output state with space
    cout << customerData << " ";
    //collect zip
    inputfile >> customerData;
    //output city state and zip
    cout << customerData << endl;
    //collect amount owed
    inputfile >> numberData;
    numberData = numberData / 100;
    cout << "Amount owed: $" << setprecision(2) << fixed << numberData << endl << endl;
    }
    //close the file
    inputfile.close();
    }
    else if (menuOptionStrInt == "4"){
    cout << "Thank you. Closing program";
    }
    else{
    cout << menuOptionStrInt << " is not a valid choice. \n" << endl;
    }
    }while (menuOptionStrInt != "4");
    return 0;
    }

    ---------------------------------------------------------------------------------------------------------------------------------

    Thanks again
     
  2. jcsd
  3. Nov 19, 2016 #2

    Borek

    User Avatar

    Staff: Mentor

    Code (Text):
    #include <stdio.h>

    void main()
    {
      printf("Please use the [cоde][/cоde] tags\n");
    }
     
  4. Nov 19, 2016 #3

    Mark44

    Staff: Mentor

    The last input you do is for minutesUsed, an integer quantity. The << operator converts a string of digit characters ('0', '1', '2', etc.) into an integer value, stopping when it encounters whitespace (space, tab, newline). If you type '3' '2' [Return], minutesUsed will be set to 32, but the input buffer will still contain the value for the Return key. If the next input you do is for a string, that character will be read into the string. The fix for this is the flush the input buffer after you have read all the values in that iteration of your loop.

    Please use code tags, as Borek mentioned. Doing so will preserve your indentation, which I hope you used. This makes your code much easier to read.

    Also, your code is monolithic, with everything happening in the main() function. Have you learned about how to write functions yet? A rough rule of thumb is that the code for a function, including main() shouldn't be more than would fit on a computer screen.
     
  5. Nov 19, 2016 #4
    Yes. So, the way this class is set up, when doing these challenges we are only able to use the concepts covered in certain chapters. As such, this project did not allow for the use of functions, though we have learned them.

    Thank you for your response. I had thought that adding the "cout << endl;" would have cleaned up everything I needed after minutesUsed. Is there a way to flush the input buffer without using getline()?

    edit: I replied with the reformatted code, as I was unable to edit my original post.
     
  6. Nov 19, 2016 #5
    Code (Text):

    #include <iostream>
    #include <iomanip>
    #include <cstring>
    #include <cmath>
    #include <fstream>

    using namespace std;

    int main(){
        //Set main variables
        string customerName, address, city, state, zip, menuOptionStrInt, menuOptionStrChar;
        int minutesUsed, amountOwedInteger, customerAmount, changeDollars, changeQuarters, changeDimes, changeNickels, changePennies, i;
        double amountOwed;
        const double PER_MINUTES_CONSTANT = 0.20, BASE_CHARGE_CONSTANT = 10.00;
        ifstream inputfile;
        //begin the do/while loop to keep the user in the program unless they select to quit
        do{
            //prompt the user with a menu presenting the options
            cout << endl << "Welcome to the Cellular Telephone System" << endl;
            cout << endl;
            cout << "1 - Process Telephone Bill" << endl;
            cout << "2 - Translate Phone Word" << endl;
            cout << "3 - Process a Data File" << endl;
            cout << "4 - Quit" << endl;
            cout << endl;
            cout << "Enter your choice: ";
            getline(cin, menuOptionStrInt);
            cout << endl;
            //begin the options from the menu. The first is for the customer to enter data
            if (menuOptionStrInt == "1"){
                cout << "Enter the name of the customer: ";
                getline(cin, customerName);
                cout << "Enter street address: ";
                getline(cin, address);
                cout << "Enter city: ";
                getline(cin, city);
                cout << "Enter state: ";
                getline(cin, state);
                cout << "Enter zip code: ";
                getline(cin, zip);
                cout << "Enter the number of minutes used: ";
                cin >> minutesUsed;
                cout << endl;
                //Calculate the amount owed
                if (minutesUsed <= 50){
                    amountOwed = BASE_CHARGE_CONSTANT;
                }
                else{
                    amountOwed = ((minutesUsed - 50) * PER_MINUTES_CONSTANT) + BASE_CHARGE_CONSTANT;
                }
                //Return all of the previously entered information and the amount owed
                cout << endl;
                cout << customerName << endl;
                cout << address << endl;
                cout << city << ", " << state << " " << zip << endl;
                cout << "Amount Owed: $" << setprecision(2) << fixed << amountOwed << endl;
                //Prompt the user to enter the amount received from the customer in pennies
                cout << endl;
                cout << "Enter the amount received from the customer: ";
                cin >> customerAmount;
                cout << endl;
                //Calculate the variables for change
                amountOwedInteger = amountOwed * 100;
     
                if (customerAmount < amountOwedInteger){
                    cout << "The amount paid is not enough to cover the cost of the bill." << endl;
                    cout << "You must pay " << amountOwedInteger - customerAmount << " more pennies to pay off the bill." << endl;
                }
                else{
                    customerAmount = customerAmount - amountOwedInteger;
                    changeDollars = customerAmount/100;
                    customerAmount %= 100;
                    changeQuarters = customerAmount/25;
                    customerAmount %= 25;
                    changeDimes = customerAmount/10;
                    customerAmount %= 10;
                    changeNickels = customerAmount/5;
                    customerAmount %= 5;
                    changePennies = customerAmount;
                    //Output the change in a formatted table
                    cout << endl;
                    cout << "Denomination" << setw(11) << "Number" << endl;
                    cout << "----------" << setw(15) << "----------" << endl;
                    cout << "Dollars " << setw(12) << changeDollars << endl;
                    cout << "Quarters " << setw(11) << changeQuarters << endl;
                    cout << "Dimes " << setw(14) << changeDimes << endl;
                    cout << "Nickels " << setw(12) << changeNickels << endl;
                    cout << "Pennies " << setw(12) << changePennies << endl;
                }
            }
            else if (menuOptionStrInt == "2"){
                cout << "Enter the phone word: ";
                getline(cin, menuOptionStrChar);
                if (menuOptionStrChar.length() != 8){
                    cout << endl << "You must enter a value in the following format\n\n`XXX-XXXX`\n\nwhere `X` is a letter and the `-`\nis a simple dash." << endl;
                    continue;
                }
                else if (menuOptionStrChar.at(3) != '-'){
                    cout << endl << "You must enter a value in the following format\n\n`XXX-XXXX`\n\nwhere `X` is a letter and the`-`\nis a simple dash." << endl;
                    continue;
                }
                cout << endl << menuOptionStrChar << " translates to ";
                for(i = 0; i < menuOptionStrChar.length(); i++){
                    int number;
                    if ((menuOptionStrChar.at(i) >= 'A' && menuOptionStrChar.at(i) <= 'Z') || (menuOptionStrChar.at(i) >= 'a' && menuOptionStrChar.at(i) <= 'z') || (menuOptionStrChar.at(i) == '-')){
                        switch (menuOptionStrChar.at(i)){
                            case '-':
                            cout << "-";
                            continue;
                            break;
                           
                            case 'A':
                            case 'a':
                           case 'B':
                            case 'b':
                           case 'C':
                            case 'c':
                          number = 2;
                            break;
                       
                            case 'D':
                            case 'd':
                           case 'E':
                            case 'e':
                           case 'F':
                            case 'f':
                          number = 3;
                            break;
                       
                            case 'G':
                            case 'g':
                           case 'H':
                            case 'h':
                           case 'I':
                            case 'i':
                          number = 4;
                            break;
                       
                              case 'J':
                            case 'j':
                           case 'K':
                            case 'k':
                           case 'L':
                            case 'l':
                          number = 5;
                            break;
                       
                            case 'M':
                            case 'm':
                           case 'N':
                            case 'n':
                           case 'O':
                            case 'o':
                          number = 6;
                            break;
                       
                            case 'P':
                            case 'p':
                           case 'Q':
                            case 'q':
                           case 'R':
                            case 'r':
                            case 'S':
                            case 's':
                          number = 7;
                            break;
                       
                            case 'T':
                            case 't':
                           case 'U':
                            case 'u':
                           case 'V':
                            case 'v':
                          number = 8;
                            break;
                       
                            case 'W':
                            case 'w':
                           case 'X':
                            case 'x':
                           case 'Y':
                            case 'y':
                            case 'Z':
                            case 'z':
                          number = 9;
                            break;
                          }
                        cout << number;
                    }
                    //This line spits out a '*' whenever a non valid, but correctly formatted, letter is entered
                    else{
                        cout << "*";
                    }
                }
                cout << endl;
            }
            //option 3 is for reading a data file containing information from option 1
            else if (menuOptionStrInt == "3"){
                //string variable for spitting out data
                string customerData;
                double numberData;
                //open file
                inputfile.open("TelephoneData.txt");
                //create loop to read data per entry based on the expected format
                while ((inputfile >> customerData) || (inputfile >> numberData)){
                    //first name output
                    cout << customerData;
                    //move to last name
                    inputfile >> customerData;
                    //space and the last name output and endline
                    cout << " " << customerData << endl;
                    //move to numeric part of address
                    inputfile >> customerData;
                    //output numeric part of address and add space
                    cout << customerData;
                    //grab text part of address
                    getline(inputfile, customerData);
                    //output text part of address and end line
                    cout << customerData << endl;
                    //collect city
                    inputfile >> customerData;
                    //out put city with no space, but add comma
                    cout << customerData << ", ";
                    //collect state
                    inputfile >> customerData;
                    //output state with space
                    cout << customerData << " ";
                    //collect zip
                    inputfile >> customerData;
                    //output city state and zip
                    cout << customerData << endl;
                    //collect amount owed
                    inputfile >> numberData;
                    numberData = numberData / 100;
                    cout << "Amount owed: $" << setprecision(2) << fixed << numberData << endl << endl;
                    }
                //close the file
                inputfile.close();
                }
            else if (menuOptionStrInt == "4"){
                cout << "Thank you. Closing program";
            }
            else{
                cout << menuOptionStrInt << " is not a valid choice. \n" << endl;
            }
        }while (menuOptionStrInt != "4");
        return 0;
    }
     
     
  7. Nov 19, 2016 #6

    Mark44

    Staff: Mentor

    What you did with cout has nothing to do with the input buffer. The C standard library has a function named fflush(), but I don't see a C++ counterpart. You could do this:
    Code (C):

    char ch;
    cin >> ch;
    That should get rid of any character remaining in the input buffer.
     
  8. Nov 19, 2016 #7

    jtbell

    User Avatar

    Staff: Mentor

    You can use the ignore() member function of istream (including cin):

    cin.ignore(80, '\n');

    tells cin to read and discard 80 characters, or until it reaches a '\n' (newline), whichever comes first. You can change 80 to some other number according to your taste or requirements (I usually use 80 because that's the traditional line length on old-fashioned text terminals), and you can use any other character as the terminator. (' ' (space) is a common choice for certain applications). That terminating character is discarded, so the next input begins at the following character.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Flushing Data in Loop? -- Keep Entering Empty Space
  1. Data Structure (Replies: 1)

Loading...