function to gather data using ampersand

I have to use a void function (using ampersand) to gather good data and put bad data in an error file. I am kind of stuck and have no idea what to do next. This is what i have so far. Thanks for any help.


void GetData (int & ID, int & Units, int & Points, int & UnitError, int &PointsError, ifstream & Infile, ofstream &
Errorfile){
Infile >> ID >> Units >> Points; //Get student data from Infile
UnitError = Units < 0 || Units > 250; //Check for Units, Points errors
PointsError = Points < 0 II Points > 4 * Units;
if (UnitError){ // Output invalid date to Errorfile
Errorfile <<"Units error in record: "<< ID << " " <<Units<< " " <<Points;
if (PointsError)
Errorfile <<"Points error in record: "<< ID <<" " <<Units<< " " << Points;

int main(){

//opening input, output and error files
ofstream outFile ("outfile.txt");
ofstream errorFile ("errorFile.txt");
ifstream inFile ("lab6.txt");

string name;
double incost, excost, intcost, extcost, total=0;
double interiorCost, exteriorCost, totalint, totalext;
int num, infeet, exfeet, linecount=0, baddata=false;

//Error message
if (!outFile){
cout << "Cannot open file, terminating the program. ";
return 0;
}
if (!errorFile){
cout << "Cannot open file, terminating the program.";
return 0;
}
if (!inFile){
cout << "Cannot open file, terminating the program.";
return 0;
}
//loop eof
while (!inFile.eof()){
//read data
getData(name, num, infeet, incost, exfeet, excost, inFile, outFile, errorFile, baddata);
if(!baddata){
calculation(infeet, incost,
totalint, exfeet, excost, totalext, total, inFile, errorFile);
sendData(name, num, totalint, totalext, total, outFile);
}
Hello fups,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



When posting code it is best to post a complete program that can be compiled and tested.

You should have compiled your code and ask about any errors that you do not understand. Also post the complete error message not what you think it means, you are usually wrong.

The code that you post is not even complete. There are several missing closing }s.

You define the function "GetData", but you call "getData". Next the parameters in the function call need to match the parameters in the function definition. In both type and order.

In the line: PointsError = Points < 0 II Points > 4 * Units; I am not sure what you are trying to do, but it does not work that way.

In the while loop: while (!inFile.eof()). This is not going to work the way that you think it will. You are checking for "eof" before you actually read and might set the "eof" bit. It tends to give 1 extra loop before it fails. If you must use the ".eof()" function there is a way to fix that.

Something to start with while I look deeper into the program.

Andy
Without knowing the format of the input data, there's not much can be done.

getData() has different arguments to the given GetData() ?? The calculation() and sendData() functions are missing. getData() should return an istream& so that it can be used in the file read loop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <fstream>
#include <iostream>
using namespace std;

void GetData(int& ID, int& Units, int& Points, int& UnitError, int& PointsError, ifstream& Infile, ofstream& Errorfile) {
	Infile >> ID >> Units >> Points; //Get student data from Infile

	UnitError = Units < 0 || Units > 250; //Check for Units, Points errors
	PointsError = Points < 0 || Points > 4 * Units;

	if (UnitError) // Output invalid date to Errorfile
		Errorfile << "Units error in record: " << ID << " " << Units << " " << Points << '\n';

	if (PointsError)
		Errorfile << "Points error in record: " << ID << " " << Units << " " << Points << '\n';
}

int main()
{
	//opening input, output and error files
	ofstream outFile("outfile.txt");
	ofstream errorFile("errorFile.txt");
	ifstream inFile("lab6.txt");

	//Error message
	if (!outFile) {
		cout << "Cannot open file, terminating the program.\n";
		return 0;
	}

	if (!errorFile) {
		cout << "Cannot open file, terminating the program.\n";
		return 0;
	}

	if (!inFile) {
		cout << "Cannot open file, terminating the program.\n";
		return 0;
	}

	string name;
	double incost, excost, intcost, extcost, total = 0;
	double interiorCost, exteriorCost, totalint, totalext;
	int num, infeet, exfeet, linecount = 0, baddata = false;

	while (getData(name, num, infeet, incost, exfeet, excost, inFile, outFile, errorFile, baddata)) {
		if (!baddata) {
			calculation(infeet, incost, totalint, exfeet, excost, totalext, total, inFile, errorFile);
			sendData(name, num, totalint, totalext, total, outFile);
		}
	}
}


Further guidance when the input file format is provided - and what the program is trying to accomplish.
Hello fups,

As seeplus mentioned when your program has an input file it is best to include that file, or a good sample if large, so that everyone can use the same information. It also helps to spot problems in your code when reading the file.

To start with "main" I did this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
int main()
{
    //opening input, output and error files
    std::ofstream outFile("outfile.txt");

    if (!outFile)
    {
	    //std::cout << "\n File " << std::quoted(outFileName) << " did not open" << std::endl;
        std::cout << "\n File \"" << "outfile.txt" << "\" did not open." << std::endl;

	    return 1;
    }

    std::ofstream errorFile("errorFile.txt");

    if (!errorFile)
    {
        //std::cout << "\n File " << std::quoted(outFileName) << " did not open" << std::endl;
        std::cout << "\n File \"" << "errorFile.txt" << "\" did not open." << std::endl;

        return 2;
    }

    std::ifstream inFile("lab6.txt");

    if (!inFile)
    {
        //std::cout << "\n File " << std::quoted(inFileName) << " did not open." << std::endl;
        std::cout << "\n File \"" << "lab6.txt" << "\" did not open." << std::endl;

        return 3;
    }

This or seeplus's version will work, but this needs to be done before the program continues. The point in your code where you did this works, but why define variables and reserve space if you do not need to.

In the above if statement returning (0) zero means that there is no problem. Returning any number other than (0) zero means there is a problem. As you can see I tend to use positive numbers, but negative numbers will work.

In the function "GetData" you define your variables, but you give them different names, since the variables are being passed by reference you should use the same name as you defined them in "main". It helps to keep everything straight. Right now the function defines "ID" as the first parameter, but in "main" there is no variable called "ID" or even "id" which makes it hard to know what variable in "main" needs to be passed to the function.

Most times being consistent in the variable names if better than changing the variable names at the function which can be confusing.

It is a little thing, but there are 3 ways to pass a variable by reference.
1
2
3
4
5
int& id

int & id

int &id

It does not matter which form you use, they are all the same in the end, but be consistent in its use. It makes the code easier to read and follow.

I did not get that far yet, but seeplus's while loop condition is the better way to read a file of unknown length.

You also need to pass "badData" to the function and change the variable if needed. I was also thinking the "badData" would work better as a "bool" and not an "int".

In "main" you should initialize all the variables when defined:
1
2
3
4
int num{}, infeet{}, exfeet{}, linecount{}, badData{};
double incost{}, excost{}, intcost{}, extcost{}, total{};
double interiorCost{}, exteriorCost{}, totalint{}, totalext{};
std::string name;

Especially variable the hold a total of something. You do not want to add to a garbage value of (-858993460), for an "int", or (-9.2559631349317831e+64), for a double. Your numbers may be different, but that is what I usually get for a garbage value.

From C++11 on the uniform initializer, the {}s, make it very easy. Empty the compiles will use the correct form of (0) zero based on the variable type. Or yo can put a number between the {}s to give it a starting value.

"std::string"s are empty when defined and do not need initialized.

Andy
Andy
I want to say thanks for all the input and taking the time to explain. I am having a hard time understanding how to pull the data using a void function with ampers and. I think i will have to try from the start again, I was reading what i put and your feed back and noticed i am all over the place. I will add what it is im trying to do and any direction would be great. Thanks again.

Function 1: (must use void function with ampersand) Read the data for one job from a file (see data below). Validate that none of the numbers are
negative. Return the data from good records to main and write error records onto a separate file.
Function 2: Determine the cost for interior painting, the cost for exterior painting, and the cost for the entire
paint job. Any painting estimate greater than $1000.00 receives a 10% discount. Return all calculated values to
main.
Function 3: Label and output all good data (customer initials, customer account number, interior square feet, cost
per interior square feet, exterior square feet, cost per exterior square feet, total interior cost, total exterior cost,
any discount and total cost) to the screen.

Data File
ABC 1234 400 3.50 850 5.50
DEF 1345 100 5.25 200 2.75
GHI 2346 200 10.00 0 0.0
JKL 4567 375 4.00 50 4.00
MNO 5463 200 -5.0 150 3.00
PQR 679 0 0.0 100 3.50
STU 6879 100 0.0 -100 0.0
VWX 7348 0 0.0 750 0.0
XYZ 9012 -24 5.00 -50 5.00
Helllo fups,

Thank you for the instructions and the input file. The only thing missing for now is a label on the input to say what each field is.

Using the ampersand as you say really means to pass the variables by reference. Meaning that you are using the variables where they are defined and sent to the function. This may be of some help:
https://www.learncpp.com/cpp-tutorial/introduction-to-function-parameters-and-arguments/ Also the beginning of chapter 2 would be good to look at.

Your program can work, but you need to define all the variables that you need to read from the file in "main" and pass the correct variables to the function.

As soon as I know what the numeric variables are in the data file I can discus it better.

For now I will see what I can come up with.

Andy
ok so here is my shot at fixing my mess. Just a heads up, i guess i am having hard time with using a function to get the data and not accepting the bad data( the negatives in the data in this case). im getting and endless loop and am trying to fix it but i am still not able to pull the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;
void getdata(int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile);
int main()
{
ifstream inFile ("lab6.txt)");
ofstream outFile ("outfile.txt");
ofstream errorFile ("errorFile.txt");

string name;
int accountNumber, inFeet, exFeet;
double costinFeet, costexFeet, errorinFeet, errorcostinFeet, errorexFeet;


if (!outFile){
  cout << "Cannot open file, terminating the program. ";
        return 0;
}
if (!errorFile){
  cout << "Cannot open file, terminating the program.";
        return 0;
}    
if (!inFile){
  cout << "Cannot open file, terminating the program.";
}
while(
    return 0;
}
void getdata(int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile){
    inFile >> inFeet >> costinFeet >> exFeet >> costexFeet;
    errorinFeet = inFeet < 0;
    errorcostinFeet = costinFeet < 0;  
    errorexFeet = exFeet < 0;
if (errorinFeet){
    errorFile << "inFeet error: " << inFeet << costinFeet << exFeet;
}
if(errorcostinFeet){
    errorFile << "costinFeet error: " << inFeet << costinFeet << exFeet;
}
if(errorexFeet){
    errorFile << "exFeet error: " << inFeet << costinFeet << exFeet;
}
}

ABC 1234 400 3.50 850 5.50


This has 6 fields per line. I'm guessing these are
name acct infeet costinfeet exfeet costexfeet

 
inFile >> inFeet >> costinFeet >> exFeet >> costexFeet;


but this only reads 4 fields - what about reading name and acct?

For the file read, as you can't return ifstream froim getdata(), you need something like (not tried):

1
2
3
4
5
6
7
while (true) {
    getdata(....);
    if (!inFile)
        break;

    //Process data here
}

Last edited on
Hello fups,

Your new code is a little better, but still not quite right.

I managed to get the first code to print this on the screen:

  1  ABC 1234   400   3.50   850   5.50
  2  DEF 1345   100   5.25   200   2.75
  3  GHI 2346   200  10.00     0   0.00
  4  JKL 4567   375   4.00    50   4.00
  5  MNO 5463   200  -5.00   150   3.00
  6  PQR  679     0   0.00   100   3.50
  7  STU 6879   100   0.00  -100   0.00
  8  VWX 7348     0   0.00   750   0.00
  9  XYZ 9012   -24   5.00   -50   5.00


Instead of trying to fix the whole program at 1 time work on it in small parts. Until you can get the read part working properly there is no point in doing anything else.

To make your first code work I did this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
GetData(inFile, errorFile, name, id, inFeet, inCost, exFeet, exCost, badData, lineCount);  //read data

//loop eof
while (!inFile.eof())
{
    if (!badData)
    {
        std::cout <<
            "\n" << std::setw(3) << lineCount << std::setw(5) << name << ' ' << std::setw(4) << id << ' '
            << std::setw(5) << inFeet << ' ' << std::setw(6) << inCost << ' '
            << std::setw(5) << exFeet << ' ' << std::setw(6) << exCost;
            
        //calculation(infeet, inCost, totalInt, exFeet, exCost, totalExt, total, inFile, errorFile);

        //sendData(name, id, totalInt, totalExt, total, outFile);
    }
    else
    {
        std::cerr << "\n     An apporiate error message\n\n";
    }

    GetData(inFile, errorFile, name, id, inFeet, inCost, exFeet, exCost, badData, lineCount);  //read data
}  // <--- Missing.

return 0;  // <--- Not required, but makes a good break point. 

If you do not have to use the ".eof()" function in the while condition then seeplus's method should work well. I have not tried it yet.

Line 22 is the last thing you need to do B4 you check for "eof".

Line 1 is there to read the first line and see if it sets "eof" B4 the while loop.

In your first code other than needing some better variable names like you used in your second code it can be made to work. First you need to know what is wrong then work in small steps or parts.

Andy
This will read the file, check for errors and display the valid data. The code for the required processing (not described) now needs to be added. As the original code has the same error message for each file not opened, this has been condensed into one test.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;

void getdata(string& name, int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile);

int main()
{
	ifstream inFile("lab6.txt");
	ofstream outFile("outfile.txt");
	ofstream errorFile("errorFile.txt");

	if (!outFile || !errorFile || !inFile)
		return(cout << "Cannot open file, terminating the program. "), 1;

	while (true) {
		string name;
		int accountNumber {}, inFeet {}, exFeet {};
		double costinFeet {}, costexFeet {}, errorinFeet {}, errorcostinFeet {}, errorexFeet {};

		getdata(name, accountNumber, inFeet, costinFeet, exFeet, costexFeet, errorinFeet, errorcostinFeet, errorexFeet, inFile, outFile, errorFile);

		if (!inFile)
			break;

		if (errorinFeet + errorcostinFeet + errorexFeet == 0) {
			// process data here - display data for testing purposes

			cout << name << " " << accountNumber << " " << inFeet << " " << costinFeet << " " << exFeet << " " << costexFeet << '\n';
		}
	}
}

void getdata(string& name, int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile)
{
	inFile >> name >> accountNumber >> inFeet >> costinFeet >> exFeet >> costexFeet;

	errorinFeet = inFeet < 0;
	errorcostinFeet = costinFeet < 0;
	errorexFeet = exFeet < 0;

	if (errorinFeet) {
		errorFile << "inFeet error: " << inFeet << costinFeet << exFeet << '\n';
	}

	if (errorcostinFeet) {
		errorFile << "costinFeet error: " << inFeet << costinFeet << exFeet << '\n';
	}

	if (errorexFeet) {
		errorFile << "exFeet error: " << inFeet << costinFeet << exFeet << '\n';
	}
}

Okay so I have been working on this since yesterday and I have gotten far thanks to your feed back. I am getting some of the data but it seems mixed, any help would be appreciated. I am trying to learn and realize i am going to make mistakes. Thanks again for the input.

My outFile:
Customer name :
Account number: 1234
Interior square feet: 400
Exterior cost per square feet: 3.5
Exterior square feet: 850
Exterior cost per square feet: 5.5
Total interior cost: 1400
Total exterior cost: 4675
Discount: 607.5
Total: 6075

My errorFile:
infeet in record error: 400 3.5 850



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

// Get Data
void getData(string name, int& num, int& infeet, double& incost, int& exfeet, double& excost, ifstream& inFile, ofstream& outFile, ofstream& errorFile, int& baddata);
void calculation(int inFeet, double incost, int exFeet, double excost, double& totalin, double& totalex,double& discount, double& total);
void sendData(string name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile);

int main(){
    
//opening input, output and error files
ofstream outFile;
ofstream errorFile;
ifstream inFile;

string name;
double incost, excost, intcost, extcost,discount = 0, total=0;
double interiorCost, exteriorCost, totalin=0, totalex=0;
int num, inFeet, exFeet, linecount=0, baddata=false;



//loop eof
 // this is what u helped me understand on thursday
  getData(name, num, inFeet, incost, exFeet, excost, inFile, outFile, errorFile, baddata);
    if(!baddata){ // this is where i get lost 
      calculation(inFeet, incost, exFeet, excost, totalin, totalex,discount, total);
      sendData(name, num, inFeet, incost, exFeet, excost, totalin, totalex, discount, total, outFile);
    }
}
    
 



//GetData
void getData(string name, int& num, int& infeet, double& incost, int& exfeet, double& excost, ifstream& inFile, ofstream& outFile, ofstream& errorFile, int& baddata){
  inFile.open("lab6.txt");
  double i=0;
  if(!inFile){
    cout << "Error" << endl;
    exit(1);}
    outFile.open ("outfile.txt");
  if(!outFile){
    cout << "Error outfile" << endl;
  }
    errorFile.open("errorFile.txt");
  if(!errorFile){
    cout << "Error errorFile" << endl;
  }
while(!inFile.eof()){
    inFile >> name >> num >> infeet >> incost >> exfeet >> excost;
     
if(!baddata){
    errorFile << "infeet in record error: " << infeet << " " << incost << " " << exfeet;
    errorFile.close();
    inFile.close();
    
}
else{
    outFile << setw(5) << left << setprecision(10);
    outFile << name << " " << num << " "<< infeet << " " << incost << " " << exfeet << " "<< excost << endl;
    outFile.close();
    
}
} 
} 


void calculation(int inFeet, double incost, int exFeet, double excost, double& totalin, double& totalex,double& discount, double& total){
  totalin = inFeet * incost;
  totalex = exFeet * excost;
  total = totalin + totalex;
  
  if(total>1000){
    discount = total * .10;
}
}
void sendData(string name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile){
    outFile << "Customer name : " << name << endl;
    outFile << "Account number: " << num << endl;
    outFile << "Interior square feet: " << inFeet << endl;
    outFile << "Exterior cost per square feet: " << incost << endl;
    outFile << "Exterior square feet: " << exFeet << endl;
    outFile << "Exterior cost per square feet: " << excost << endl;
    outFile << "Total interior cost: " << totalin << endl;
    outFile << "Total exterior cost: " << totalex << endl;
    outFile << "Discount: " << discount << endl;
    outFile << "Total: " << total << endl;
  }
Last edited on
Hello fups,

fups wrote:

Okay so I have been working on this since yesterday and I have gotten far thanks to your feed back.


It looks like you have gotten far in the wrong direction.

Everything looks good for now with this part:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

// Get Data
int getData(string name, int& num, int& infeet, double& incost, int& exfeet, double& excost, ifstream& inFile, ofstream& outFile, ofstream& errorFile, int& baddata);
void calculation(int inFeet, double incost, int exFeet, double excost, double& totalin, double& totalex, double& discount, double& total);
void sendData(string name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile);

int main()
{
    //opening input, output and error files
    ofstream outFile;
    ofstream errorFile;
    ifstream inFile;

    string name;

I did make 1 change on the return value of line 9.

After this most of your variables need to be initialized not just some of them. ALL of them. It will save you on problems now and in the future.

The call to the function I wrote this way:
1
2
if (result = getData(name, num, inFeet, incost, exFeet, excost, inFile, outFile, errorFile, baddata))
    return result;


For the function "getData".

You start by opening the file for input then check is it worked. The concept is good, but DO NOT use "exit". This is a C function that does not know about C++ classes, so they are not cleaned up B4 an immediate termination of the program. It is better to use "return". The number following "return" needs to be a number that is not (0) zero. I like using positive numbers, but negative numbers will work.

Next you open 2 output files and check them. The problem is if there is a problem you allow the program to continue as if nothing is wrong. Not a good idea.

I have already showed you the way I do this and seeplus has shown his way. Pay attention.

I have already told you why the while loop will not work. If you did not understand say so and I will try a different approach.

Inside the while loop you read the file, but never verify what was read. So when you get to the if statement "badData" comes into the function with a value of (0) zero or false, so the if statement if(!baddata) will always evaluate to true.

Between the read and the if statement you never check if what was read is valid or not. Since the variable "badData" never changes it starting value there is not much point to the if/else statements.

Since I changed the return value of the function you need to end the function with "return 0;" meaning that everything work correctly and nothing is wrong. Mostly you need it to avoid a compiler warning.

Not sure about the "calculation" function yet as I have not worked on that part.

In the "sendData" function you can write it as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void sendData(string name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile)
{
    outFile
        << "Customer name : " << name << '\n'
        << "Account number: " << num << '\n'
        << "Interior square feet: " << inFeet << '\n'
        << "Exterior cost per square feet: " << incost << '\n'
        << "Exterior square feet: " << exFeet << '\n'
        << "Exterior cost per square feet: " << excost << '\n'
        << "Total interior cost: " << totalin << '\n'
        << "Total exterior cost: " << totalex << '\n'
        << "Discount: " << discount << '\n'
        << "Total: " << total << endl;
}

You do not need every line to start with "outFile" or even "std::cout" and end with an "endl". The insertion operator (<<) will chain everything together. If you feel the need use "endl" on the last line, but the "\n" should do the same thing.

Andy
Hello fups,

With a few changes to the program, more for output appearance, your program produces this:

infeet in record error: ABC   -400  -3.50   -850
infeet in record error: DEF    100   5.25    200
infeet in record error: GHI    200  10.00      0
infeet in record error: JKL    375   4.00     50
infeet in record error: MNO    200  -5.00    150
infeet in record error: PQR      0   0.00    100
infeet in record error: STU    100   0.00   -100
infeet in record error: VWX      0   0.00    750
infeet in record error: XYZ    -24   5.00    -50
infeet in record error: XYZ    -24   5.00    -50


Notice how your while loop processed the last read twice.

Andy
Consider based upon my previous code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;

void getdata(string& name, int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile);
void calculation(int inFeet, double incost, int exFeet, double excost, double& totalin, double& totalex, double& discount, double& total);
void sendData(const string& name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile);

int main()
{
	ifstream inFile("lab6.txt");
	ofstream outFile("outfile.txt");
	ofstream errorFile("errorFile.txt");

	if (!outFile || !errorFile || !inFile)
		return(cout << "Cannot open file, terminating the program. "), 1;

	while (true) {
		string name;
		int accountNumber {}, inFeet {}, exFeet {};
		double costinFeet {}, costexFeet {}, errorinFeet {}, errorcostinFeet {}, errorexFeet {};

		getdata(name, accountNumber, inFeet, costinFeet, exFeet, costexFeet, errorinFeet, errorcostinFeet, errorexFeet, inFile, outFile, errorFile);

		if (!inFile)
			break;

		if (errorinFeet + errorcostinFeet + errorexFeet == 0) {
			// process data here - display data for testing purposes
			//cout << name << " " << accountNumber << " " << inFeet << " " << costinFeet << " " << exFeet << " " << costexFeet << '\n';

			double totalin {}, totalex {}, discount {}, total {};

			calculation(inFeet, costinFeet, exFeet, costexFeet, totalin, totalex, discount, total);
			sendData(name, accountNumber, inFeet, costinFeet, exFeet, costexFeet, totalin, totalex, discount, total, outFile);
		}
	}
}

void getdata(string& name, int& accountNumber, int& inFeet, double& costinFeet, int& exFeet, double& costexFeet, double& errorinFeet, double& errorcostinFeet, double& errorexFeet, ifstream& inFile, ofstream& outFile, ofstream& errorFile)
{
	if (inFile >> name >> accountNumber >> inFeet >> costinFeet >> exFeet >> costexFeet) {
		errorinFeet = inFeet <= 0;
		errorcostinFeet = costinFeet <= 0;
		errorexFeet = exFeet <= 0;

		if (errorinFeet) {
			errorFile << "inFeet error: " << name << ' ' << accountNumber << ' ' << inFeet << ' ' << costinFeet << ' ' << exFeet << '\n';
		}

		if (errorcostinFeet) {
			errorFile << "costinFeet error: " << name << ' ' << accountNumber << ' ' << inFeet << ' ' << costinFeet << ' ' << exFeet << '\n';
		}

		if (errorexFeet) {
			errorFile << "exFeet error: " << name << ' ' << accountNumber << ' ' << inFeet << ' ' << costinFeet << ' ' << exFeet << '\n';
		}
	}
}

void calculation(int inFeet, double incost, int exFeet, double excost, double& totalin, double& totalex, double& discount, double& total)
{
	totalin = inFeet * incost;
	totalex = exFeet * excost;
	total = totalin + totalex;

	if (total > 1000)
		discount = total * .10;
}

void sendData(const string& name, int num, int inFeet, double incost, int exFeet, double excost, double totalin, double totalex, double discount, double total, ofstream& outFile)
{
	outFile << "Customer name : " << name << '\n';
	outFile << "Account number: " << num << '\n';
	outFile << "Interior square feet: " << inFeet << '\n';
	outFile << "Exterior cost per square feet: " << incost << '\n';
	outFile << "Exterior square feet: " << exFeet << '\n';
	outFile << "Exterior cost per square feet: " << excost << '\n';
	outFile << "Total interior cost: " << totalin << '\n';
	outFile << "Total exterior cost: " << totalex << '\n';
	outFile << "Discount: " << discount << '\n';
	outFile << "Total: " << total << '\n';
}


outfile.txt

Customer name : ABC
Account number: 1234
Interior square feet: 400
Exterior cost per square feet: 3.5
Exterior square feet: 850
Exterior cost per square feet: 5.5
Total interior cost: 1400
Total exterior cost: 4675
Discount: 607.5
Total: 6075
Customer name : DEF
Account number: 1345
Interior square feet: 100
Exterior cost per square feet: 5.25
Exterior square feet: 200
Exterior cost per square feet: 2.75
Total interior cost: 525
Total exterior cost: 550
Discount: 107.5
Total: 1075
Customer name : JKL
Account number: 4567
Interior square feet: 375
Exterior cost per square feet: 4
Exterior square feet: 50
Exterior cost per square feet: 4
Total interior cost: 1500
Total exterior cost: 200
Discount: 170
Total: 1700


errorfile.txt

exFeet error: GHI 2346 200 10 0
costinFeet error: MNO 5463 200 -5 150
inFeet error: PQR 679 0 0 100
costinFeet error: PQR 679 0 0 100
costinFeet error: STU 6879 100 0 -100
exFeet error: STU 6879 100 0 -100
inFeet error: VWX 7348 0 0 750
costinFeet error: VWX 7348 0 0 750
inFeet error: XYZ 9012 -24 5 -50
exFeet error: XYZ 9012 -24 5 -50

Last edited on
Topic archived. No new replies allowed.