Pregunta

I posted this program yesterday (in case you didn't see it yesterday, I re-posted a basic summary below), and you guys showed me what was wrong with my Boolean logic, so everything is working as I want it to, but I am processing the last line twice if I use something like while(inFile), or while(!inFile.eof()), etc. Because of this, I wanted to use stringstream, so that I can process the input line by line.

Since the input data is not just one data type (it is int, int, char, char, float), I used stringstream in the following way (as also shown in my code below):

while (getline(inFile, line)){

istringstream ss(line);

while(ss >> numAdults >> numChildren >> mealType >> dayType >> depositAmount){

These are my variables that I'm trying to read in my input file, in the correct order. What happens is that I get 4 lines of output in my billing_statement text file and 3 lines of output in the error_report text file (There are a total of 13 lines in the input text file). It seems like some of the lines might be combined. Appreciate the assistance here.

Thanks.

INPUT FILE:

10 0 S Y 100.00

27 3 D Y 57.50

125 17 D N 0.00

4 0 S N 25.00

0 25 S Y 23.75

250 43 D N 500.00

0 0 D N 0.0

10 0 R Y 10.00

17 3 D R 15.00

5 0 D Y 275.00

-3 10 D Y 20.00

14 -1 S N 30.00

20 3 D Y -10.00

Here is a link to my thread yesterday, which explains my program, although it shouldn't be needed for my specific question...

C++: Mock Catering Company Billing Program - Not able to ouput bad data to error file

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>


using namespace std;

void getData(int &, int &, char &, char &, float &);
void checkValid(int &, int &, char &, char &, float &, bool &);
void calcData(int, int, char, char, float, float &, float &, float &, float &);
void sendData(int, int, char, char, float, float &, float &, float &, float &);

ifstream inFile;
ofstream outFile("Billing_Statement.txt");
ofstream error_Report("Error_Report.txt");

//Declare the tax rate and weekend surcharge as constants.

const float taxRate = 0.18;
const float weekendSurcharge = .07;

int main()
{

bool valid = true;
float mealCost;
float totalTax;
float totalSurcharge;
float discountAmount;
int numAdults;
int numChildren;
char mealType;
char dayType;
float depositAmount;
string line;

cout << "\nThis program will calculate data for a catering company " << endl;

outFile << " Adults " << "Children  " << "Meal " << " Weekend " << setw(9) << "Deposit "
<< setw(6) << "Tax" << setw(11) << "Surcharge" << setw(10) << "Discount" << setw(12) << 
"Meal Cost" << endl;
error_Report << " Adults " << "Children  " << "Meal " << " Weekend " << setw(9) << 
"Deposit " << endl;

inFile.open("file.txt");

if (!inFile) {
cout << "\nError: File could not be opened. ";
//exit(1);
}

while (getline(inFile, line)){

istringstream ss(line);

while(ss >> numAdults >> numChildren >> mealType >> dayType >> depositAmount){
getData(numAdults, numChildren, mealType, dayType, depositAmount);
checkValid(numAdults, numChildren, mealType, dayType, depositAmount, valid);

if (valid == true)
{
    calcData(numAdults, numChildren, mealType, dayType, depositAmount, totalTax,
 totalSurcharge, discountAmount, mealCost);
    sendData(numAdults, numChildren, mealType, dayType, depositAmount, mealCost, 
totalTax, totalSurcharge, discountAmount);
}}
}

cout << "\nA copy of this has created for your convenience in the file, 
Billing_Statement.txt" << endl;

inFile.close();
outFile.close();
error_Report.close();

return 0;

}

void getData(int & numAdults, int & numChildren, char & mealType, char & dayType, float
& depositAmount)
{
inFile >> numAdults >> numChildren >> mealType >> dayType >> depositAmount;
}

void checkValid(int & numAdults, int & numChildren, char & mealType, char & dayType, 
float & depositAmount, bool & valid)
{

if (numAdults < 0 || numChildren < 0)
valid = false;
else if (!(mealType == 'D' || mealType == 'S'))
valid = false;
else if (!(dayType == 'Y' || dayType == 'N'))
valid = false;
else if (depositAmount < 0)
valid = false;

else
valid = true;

if (valid == false) {

error_Report << setw(7) << numAdults << setw(9) << numChildren << setw(6) << 
mealType << setw(9) << dayType << setw(9) << right << depositAmount << setw(8) << endl;
}
}

void calcData(int numAdults, int numChildren, char mealType, char dayType, float  
depositAmount, float & totalTax, float & totalSurcharge, float & discountAmount, float & 
mealCost)
{

if (mealType == 'S') {

mealCost = ((numAdults * 21.75) + (numChildren * (21.75 * .60)));
totalTax = mealCost * taxRate;
mealCost += taxRate;

if (dayType == 'Y') {
    totalSurcharge = mealCost * weekendSurcharge;
    mealCost += totalSurcharge;
}}

else {

mealCost = ((numAdults * 25.80) + (numChildren * (25.80 * .60)));
totalTax = mealCost * taxRate;
mealCost += taxRate;

if (dayType == 'Y') {
    totalSurcharge = mealCost * weekendSurcharge;
    mealCost += totalSurcharge;
    }
}

if (mealCost < 100) {

discountAmount = .015 * mealCost;
mealCost -= discountAmount;
}

else if (mealCost >= 100 && mealCost < 400) {

discountAmount = .025 * mealCost;
mealCost -= discountAmount;
}

else if (mealCost >= 400) {

discountAmount = .035 * mealCost;
mealCost -= discountAmount;
}
}

void sendData(int numAdults, int numChildren, char mealType, char dayType, float
depositAmount, float &mealCost, float &totalTax, float &totalSurcharge, float 
&discountAmount)
{
outFile << fixed << showpoint << setprecision(2);
outFile << setw(7) << numAdults << setw(9) << numChildren << setw(6) << mealType <<
setw(9) << dayType << setw(9) << right << depositAmount << setw(8) << totalTax << 
setw(10) << totalSurcharge << setw(10) << right << discountAmount << setw(12) << right 
<< mealCost << endl;
}
¿Fue útil?

Solución

The problem is that your getData() function is reading input from inFile: one line is read by std::getline() and the next line is read in getData(). It seems, getData() was meant to read the data which is actually read in the nested while. As it is right now, getData() is actually harmful. I would change the code to

  1. Not use a nested while-loop but rather use an if-statement.
  2. Print the line if it couldn't be read, i.e., in the if's else-branch.
  3. Remove the use and probably the implementation of getData().
  4. Indent the code to reflect its structure.
  5. Of course, I wouldn't use std::endl but '\n'.
  6. There is no need to close() files as the destructors of the respective streams will do so anyway (the only need to use close() is when you want to deal with errors).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top