Flushing Data in Loop? -- Keep Entering Empty Space

In summary: Enter the amount of money you would like to pay: "; cin >> amountOwedInteger; cout << "Enter a dollar sign ($) if you would like to pay in pennies:
  • #1
vr0nvr0n
20
0
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
 
Technology news on Phys.org
  • #2
Code:
#include <stdio.h>

void main()
{
  printf("Please use the [cоde][/cоde] tags\n");
}
 
  • #3
vr0nvr0n said:
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?).
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.

vr0nvr0n said:
Feel free to tell me that I need to reformat this differently for ease of reference.
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.
 
  • #4
Mark44 said:
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.

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.

Mark44 said:
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.

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.
 
  • #5
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;
}
 
  • #6
vr0nvr0n said:
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()?
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:
C:
char ch;
cin >> ch;
That should get rid of any character remaining in the input buffer.
 
  • #7
vr0nvr0n said:
Is there a way to flush the input buffer without using getline()?
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.
 

1. What is the purpose of flushing data in a loop?

Flushing data in a loop is used to clear out any existing data in the loop and start fresh with new data. This is typically done to prevent any errors or conflicts that may occur if the loop is run multiple times without clearing the data.

2. How is data flushed in a loop?

Data can be flushed in a loop by using a special command or function that clears out the data stored in the loop. This can also be achieved by manually removing the data from the loop's memory.

3. Can flushing data in a loop affect the loop's performance?

Yes, flushing data in a loop can affect its performance. Depending on the size and complexity of the data being flushed, it may take longer for the loop to complete its iterations. However, flushing data can also improve performance by preventing any errors or conflicts.

4. Is it necessary to flush data in every loop?

No, it is not necessary to flush data in every loop. It is only necessary if there is a potential for errors or conflicts to occur if the data is not cleared. In some cases, flushing data may not be needed at all if the loop is not performing any critical tasks.

5. Are there any alternative methods to flushing data in a loop?

Yes, there are alternative methods to flushing data in a loop. This includes using variables with limited scope within the loop, breaking the loop when the desired data has been retrieved, or using conditional statements to determine when data should be cleared. However, flushing data in a loop is generally the most efficient and effective method.

Similar threads

  • Programming and Computer Science
Replies
3
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
3K
  • Programming and Computer Science
Replies
6
Views
2K
Back
Top