Reputation: 641
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;
}
Upvotes: 0
Views: 394
Reputation: 153810
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
while
-loop but rather use an if
-statement.if
's else
-branch.getData()
.std::endl
but '\n'
.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).Upvotes: 1