Need Help Separating Outputs

So I’ve just started programming for college and we’re now halfway through the semester. I am still VERY new at this so forgive me.

We were tasked with separating our “TotalPaid” and “TotalSold” outputs into two different text files. I want both to pull data from the “StocksBought.txt” file as well. I am able to get the output data for “TotalPaid” to go into a separate text file named “TotalPaid.txt” as you can see. However, I can’t seem to do the same for “TotalSold.txt.” There is currently no output coming out for “TotalSold.” How do I fix this? The input in the "StocksBought.txt" is 100 and it was able to give an output into the "TotalPaid.txt" file but won't give one in the "TotalPaid.txt"

Here are what the text files look like: https://imgur.com/a/gk4ASrP

Below is the C++ 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
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
	fstream inputdata;
	fstream outputdata;

	const float COMMISSION_RATE = .02;
	const float PURCHASE_PRICE = 32.87;
	const float SELLING_PRICE = 33.92;

	double amountPaid, purchCom, totalPaid,
		stocksSoldFor, sellingCom, totalReceived, profitOrLoss;

	int numberOfShares;

	inputdata.open("StocksBought.txt");
	outputdata.open("TotalPaid.txt");
	if (inputdata.fail())
	{
		cout << "There is an error within the TotalPaid text file" << endl;
	}
	else

	{
		inputdata >> numberOfShares; //User enters data respectively

		amountPaid = numberOfShares * PURCHASE_PRICE;
		purchCom = COMMISSION_RATE * amountPaid;
		totalPaid = amountPaid + purchCom;

		outputdata << "The total paid is:" << totalPaid << endl;
	}

	inputdata.open("StocksBought.txt");
	outputdata.open("TotalSold.txt");
	if (inputdata.fail())
	{
		cout << "There is an error within the TotalSold text file" << endl;
	}
	else

	{
		inputdata >> numberOfShares; //User enters data respectively

		stocksSoldFor = numberOfShares * SELLING_PRICE;
		sellingCom = COMMISSION_RATE * stocksSoldFor;
		totalReceived = stocksSoldFor - sellingCom;

		outputdata << "The total sold is:" << totalReceived << endl;
	}
	system("pause");
}
Last edited on
Hello SkytheWitcher,



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.
You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



You need to close your input and output files before you can use those file streams again.

Another option would be to leave the input file stream open until the end of the the code and use inputdata.seekg(0, std::ios::beg); to set the file pointer to the beginning of the file, so that you can read the file again.

Hope that helps,

Andy
Hello SkytheWitcher,

My apologies I was interrupted and lost my thoughts.

I wanted to ask you why the constants are floats and the rest of the variables are doubles? It is better to make them all doubles because them can cause a problem.

If you are going to use "fstream" to define the streams then in the open statement you need to tell it if the stream is for input or output or even both:
1
2
inputdata.open("StocksBought.txt", std::ios::in);
outputdata.open("TotalPaid.txt, std::ios::out");

Unlike "ifstream" and "ofstream" "fstream" has no idea what you want to do.

After you open the input file you do not really need the else part. Just the code that is in the else block. And you will find that the if statement is better as:
1
2
3
4
5
if (!inputdata)
{
    std::cout << "File \"StocksBought.txt\" did not open" << std::endl;
    return 1;
}

return 0; means a normal ending with no problems. Any number greater than zero means there is a problem and that number can help to find where the problem is.

Lastly you have a program that reads a text file for input. It is a great help if you include the contents of this file so people testing your program can use the same information and not have to guess at what might be in this file. If it is a large file five to ten lines will work for a sample.

Hope that helps,

Andy
Hey, thank you so much for replying! The new "If" statement definitely made my code look a lot more neat and organized. Much of what you said definitely helped but I ultimately still have a few problems, primarily from my lack of understanding of what you said. I still cannot get the output to go into my "TotalSold.txt" file (Oh, and the contents of the text file that is being read for input is just a simply number e.g. 100).

My professor does not seem to teach us the most efficient methods but perhaps it is all because we are all novices at this so thank you for bearing with me.

This is what my code looks like now

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
inputdata.seekg(0, std::ios::beg);// I am not sure where to put this line.
	inputdata.open("StocksBought.txt", std::ios::in);
	outputdata.open("TotalPaid.txt", std::ios::out);

	if (!inputdata)
	{
		std::cout << "File \"StocksBought.txt\" did not open" << std::endl;
		return 1;
	}
	
	{
		inputdata >> numberOfShares; //User enters data respectively

		amountPaid = numberOfShares * PURCHASE_PRICE;
		purchCom = COMMISSION_RATE * amountPaid;
		totalPaid = amountPaid + purchCom;
		outputdata << "The total paid is:" << totalPaid << endl;
	}

	{
		inputdata.open("StocksBought.txt", std::ios::in);
		outputdata.open("TotalSold.txt", std::ios::out);

		stocksSoldFor = numberOfShares * SELLING_PRICE;
		sellingCom = COMMISSION_RATE * stocksSoldFor;
		totalReceived = stocksSoldFor - sellingCom;
		outputdata << "The total sold is:" << totalReceived<< endl;
	}
	system("pause");
}
Hello SkytheWitcher, all you need to do is, deleting line 40 and replacing line 39 by: inputdata.seekg(0);

http://www.cplusplus.com/reference/istream/istream/seekg/

But need you really reading the same content from the input file twice?

I've overlooked that you aren't read other stuff besides your reading at line 30. So you could delete both lines 39 and 40
Last edited on
Hey nuderobmonkey, that definitely got it to work! I am sure my professor will be okay with it. Although, I am curious. What if I wanted the two different outputs (TotalPaid and TotalSold) to be in different text files? How can I do that?

Sreenshot: https://imgur.com/a/Bq0oP66

As you can see, the two outputs are in one text file but I do have two different text files for the two outputs. I would just like to separate them but I am not sure where to go from here.
Hello SkytheWitcher,

inputdata.seekg(0, std::ios::beg);// I am not sure where to put this line.
To give you and idea:

100 125 150 175 200
^ file pointer here when file is opened.
100 125 150 175 200
    ^ file pointer here after first read.
100 125 150 175 200
        ^ file pointer here after second read.
100 125 150 175 200
            ^ file pointer here after third read.
100 125 150 175 200
                ^ file pointer here after forth read.
100 125 150 175 200
                   ^ file pointer here after last read.

The next read will set the "EOF" bit on the file stream
because you are trying to read past "EOF".


Think about it. The use of inputdata.seekg(0); is when you are finished reading the file and need to start over. Considering that the input file will have more than two numbers in it your program will only read two numbers and not reach the end of the file. In this case using "seekg" will work. Should you reach the end of the file and the "eof" bit is set on the file stream you would have to use this:
1
2
inputdata.clear();  // <--- To reset the state bits on the stream.
inputdata.seekg(0);  // <--- To set the file pointer to the beginning. 

I still cannot get the output to go into my "TotalSold.txt" file

This is because you need to close the "outputdata" stream before you open it with a new file name. Otherwise the new stream fails to open, so the "TotalSold.txt" is never created.

My professor does not seem to teach us the most efficient methods but perhaps it is all because we are all novices at this

Been there, done that. I believe in the first class the idea is to teach the basics and leave the more advanced parts for the next classes. Some small part may be because you are a novice, but that means that you need to learn the basics first.

Back when I was taking classes my first programming class was in "Assembly language" for an IBM mainframe computer. The only thing he said during the entire ten weeks was "Read ahead. don't wait for me to lecture on what you need or you will not be able to finish your assignment". When it comes to your text book do not feel limited to the chapters or pages that you were told to read. At least look at the rest of the book and try to read what is not required. Also places like here are good sources for looking at the code of others and to ask questions.

In your code you have:
1
2
3
4
5
6
7
8
{
	inputdata >> numberOfShares; //User enters data respectively

	amountPaid = numberOfShares * PURCHASE_PRICE;
	purchCom = COMMISSION_RATE * amountPaid;
	totalPaid = amountPaid + purchCom;
	outputdata << "The total paid is:" << totalPaid << endl;
}

You do not need the {}s to define a block for every section of code. Doing so limits the scope of the program to just that block and when the block ends so will that you may have created inside that block. This can actually work against you.

After looking at your program closer I realized some problems and feel this will work better:
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
#include<iostream>
#include <iomanip>// <--- For the setprecision.
#include<fstream>

using namespace std;  // <--- Best not to use.

int main()
{
	ifstream inFile;
	ofstream outFilePaid;
	ofstream outFileSold;

	const double COMMISSION_RATE = .02;  // <--- Changed.
	const double PURCHASE_PRICE = 32.87;  // <--- Changed.
	const double SELLING_PRICE = 33.92;  // <--- Changed.

	double amountPaid, purchCom, totalPaid,
		stocksSoldFor, sellingCom, totalReceived, profitOrLoss;

	int numberOfShares;

	inFile.open("StocksBought.txt");
	outFilePaid.open("TotalPaid.txt");
	outFileSold.open("TotalSold.txt");

	if (!inFile)
	{
		std::cout << "File \"StocksBought.txt\" did not open!" << std::endl;
		return 1;
	}

	if (!outFilePaid)
	{
		std::cout << "File \"TotalPaid.txt\" has a problem!" << std::endl;
		return 2;
	}

	if (!outFileSold)
	{
		std::cout << "File \"TotalSold.txt\" has a problem!" << std::endl;
		return 3;
	}

	// <--- These need done only once.
	outFilePaid << std::fixed << std::showpoint << std::setprecision(2);
	outFileSold << std::fixed << std::showpoint << std::setprecision(2);

	while (inFile >> numberOfShares)
	{
		//inFile >> numberOfShares; //User enters data respectively  Reads from the file only once.

		amountPaid = numberOfShares * PURCHASE_PRICE;
		purchCom = COMMISSION_RATE * amountPaid;
		totalPaid = amountPaid + purchCom;

		stocksSoldFor = numberOfShares * SELLING_PRICE;
		sellingCom = COMMISSION_RATE * stocksSoldFor;
		totalReceived = stocksSoldFor - sellingCom;

		outFilePaid << "The total paid is:" << totalPaid << endl;

		outFileSold << "The total sold is:" << totalReceived << endl;

	}

	inFile.close();
	outFilePaid.close();
	outFileSold.close();

	std::cout << "\n Processing finished." << std::endl;

	// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
	//std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
	std::cout << "\n\n Press Enter to continue";
	std::cin.get();

	return 0;
}

The while loop will read everything that is in the file until the "eof" bit is set then the while condition will fail. Doing this will eliminate the need for "seekg" or having to close a file stream before opening it for a new file. And as line 50 implies that there will be more than one number in the input file. I used "100 125 150 175 200" for the "StocksBought.txt" file.

By combining the calculations as I did you can read one number, do all the calculations and write to the two output files before reading the next number and processing it.

Over time I have decided on calling the input file stream variable as inFile and output file stream variable as outFile. I found this easier to understand when writing and later reading the code. You may define the file streams anything you like, but it does help when you are consistent, i.e., you do not have to think as much.

The program produced these results:

The "TotalPaid.txt" contains:

The total paid is:3352.74
The total paid is:4190.93
The total paid is:5029.11
The total paid is:5867.30
The total paid is:6705.48



And "TotalSold.txt" contains:

The total sold is:3324.16
The total sold is:4155.20
The total sold is:4986.24
The total sold is:5817.28
The total sold is:6648.32



Hope that helps,

Andy
Hey Andy! You are the absolute best and you have made my first experience on this forum an amazing one and for that, I cannot thank you enough. I tried Stackoverflow but was met with some minor hostility due to me being new to both the forum and coding.

What you have taught me kind of clicked but also simultaneously did not (lol) but you have given me some things to study for the night. Much of the methods you used, we have not touched upon at all and may not ever in this class. It looks like I have some reading to do for which you have inspired me to do so.
Topic archived. No new replies allowed.