Stream I / O

Write a program that will add information entered from the keyboard to a text file (according to the option). It should be possible to select an operating mode by the user: adding or displaying data (menu). Provide data storage in a file in the form of a structured table using formatting tools. When displaying on the screen, the header of information will be displayed in which column the data is displayed. The file should contain only structured information without a header.
The name of the sports club, the number of visitors per day and the price of the annual subscription are entered from the keyboard, and the name of the sports club, the number of visitors per day and the profit per day are recorded in the file.
I would be grateful for the correction of errors
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
using namespace std;
int main() {
while (true) {
cout << "Show data –press 1" << endl;
cout << "Write data -press 2" << endl;
cout << "Exit –press 3" << endl;
}
int choice;
cin >> choice;
if (choice == 1) {
string club;
int quantity;
int price;
ifstream infile;
infile.open("File.txt");
if (!infile) {
cout << "Cannot open file" << endl;
return-1;
}
cout << setw(9) << "Club" << setw(9) << "Quantity" << endl << setw(9) << "Price" << endl;
while (!infile.eof()) {
infile >> club;
infile >> quantity;
infile >> price;
if (!infile.eof()) {
cout.width(9);
cout << club;
cout.width(9);
cout << quantity;
cout << endl;
cout.width(9);
cout << price;
cout << endl;
}
}
infile.close();
}
if (choice == 2) {
string club;
int quantity;
int price;
cin >> club;
cin >> quantity;
cin >> price;
fstream outfile("File.txt", ios::app);
if (!outfile) {
cout << "Cannot open file" << endl;
return-1;
}
outfile.setf(ios::left);
outfile.width(9);
outfile << club << ' ';
outfile.width(9);
outfile << quantity << endl;
outfile.width(9);
outfile << price/365 << endl;
outfile.close();
}
if (choice == 3) {
break;
}
}
system("pause");
}
Well as a starter, consider:

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>
#include <string>
#include <iomanip>
using namespace std;

int main()
{
	while (true) {
		cout << "Show data - press 1\n";
		cout << "Write data - press 2\n";
		cout << "Exit - press 3\n";

		int choice {};
		cin >> choice;

		if (choice == 1) {
			string club;
			int quantity {};
			int price {};
			ifstream infile("File.txt");

			if (!infile) {
				cout << "Cannot open file" << endl;
				return -1;
			}

			cout << setw(9) << "Club" << setw(9) << "Quantity\n" << setw(9) << "Price\n";
			while (infile >> club >> quantity >> price)
				cout << setw(9) << club << setw(9) << quantity << '\n' << setw(9) << price << '\n';
		}

		if (choice == 2) {
			string club;
			int quantity {};
			int price {};

			cin >> club;
			cin >> quantity;
			cin >> price;

			fstream outfile("File.txt", ios::app);

			if (!outfile) {
				cout << "Cannot open file" << endl;
				return -1;
			}

			outfile << left << setw(9) << club << ' ' << setw(9) << quantity << '\n' << setw(9) << price / 365 << '\n';
		}

		if (choice == 3)
			break;
	}
}


which compiles OK.
There's an eternal cycle
Not in my code as above if you enter valid values.....

Sorry, you're right, thanks
Can you tell me how to save the data in a file as a structured table using formatting tools?
Hello gvdg,


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.

Tutorials on how to use code tags:

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.


Looking over your program the first thing I notice is the while loop. line 9 starts the opening brace of the loop, but line 13 has the closing brace. Line 13 needs to come after "if (choice == 3)". Not only can the "break" statement be good, but you will stay in the loop until you enter a "3". As is the break statement is outside a loop and becomes an error.

At the end of "main" "system("pause");" is outside the closing brace of "main" and this along with the extra closing brace is an error.

I worked with your code a bit. It does not follow the directions completely, but should give you a place to start.

Something else that would help if if you provide the input file, so that everyone can be using the same information.

This is what I have reworked and mostly deals with choice 1.
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
#include<iostream>
#include<iomanip>
#include<string>

#include<fstream>

using namespace std;

int main()
{
    while (true)
    {
        cout <<
            "\n"
            " 1. Show data\n"
            " 2. Write data\n"
            " 3. Exit\n"
            "  Enter choice: ";

        int choice;

        cin >> choice;

        if (choice == 1)
        {
            string club;
            int quantity;
            int price;

            ifstream infile("File.txt");
            //infile.open("File.txt");

            if (!infile)
            {
                cout << "Cannot open file" << endl;

                return 1;
            }

            cout << "\n\n" << std::left << setw(17) << "Club" << setw(11) << "Quantity" << std::setw(9) << "Price" << '\n';
            std::cout << std::string(33, '-') << '\n';

            //while (!infile.eof())  // <--- Does not work the way you think it does. This will cause 1 extra read and its results are undetermined.
            while ((std::getline(infile, club, ',')) && infile >> quantity >> price)
            {
                //infile >> club;
                //infile >> quantity;
                //infile >> price;

                std::cout
                    << std::left
                    << std::setw(15) << club
                    << std::right
                    << std::setw(7) << quantity
                    << std::setw(10) << price
                    << '\n';

                infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. Needed B4 the next "getline".
                
                //if (!infile.eof())
                //{
                    //cout.width(9);
                    //cout << club;
                    //cout.width(9);
                    //cout << quantity;
                    //cout << endl;
                    //cout.width(9);
                    //cout << price;
                    //cout << endl;
                //}
            }
            
            std::cout << '\n';

            infile.close();
        }
// ...  choice == 2

        if (choice == 3)
        {
            std::cout << "\n\n";

            break;
        }
    }

    system("pause");
}

The order of the header files is not important, but I find this to be useful.

Moving the closing brace of the while loop down to line 82, in this example, puts most "main" in the while loop, so it will continue until you choose to "Exit".

Putting the closing brace after the menu means that you have an endless loop just printing the menu.

There is nothing wrong with the way that you set up and opened the file, but line 30 is the more preferred way and works the same.

In the if statement line 33 it makes no difference if you return a negative or positive number as long as it is not (0)zero. Personally I prefer positive numbers and the number returned can help you track down where it went wrong.

The "cout" statement at line 50 I have found much easier to work with. Using the insertion operator, (<<), you can chain many pieces into just 1 "cout" statement and it does not matter how many lines they may be on.

For line 60 the if statement is good for what you started with in your while condition, but the change I made negates it need. Also the use of the "cout" format is legal, but you should choose between using this or using "setw" and be consistent.

I would suggest using the "setw" and with a little practice you will learn how to use the width of the block to space things out. I you are not familiar with "setw" the default setting is "std::right", probably set up this way to deal with numbers, so if you need something like "std::left" for text you have to change this and then back to "std::right" for numbers.

For line 75 this is not required as the dtor of the stream object will close the file before the variable is destroyed when the block looses scope.
I have not looked at "choice 2" yet. First you need to read the file and get something to work with.

In "choice 1" you read the file and provide a nice print out to the screen. It does not look like you need to store this information in the program while it is running, but is there anything that says that you can not? Something to consider.

When I look at choice 2 does this need to add new information to the file or should it be processing the existing file or both?

Something to work on for a while.

Andy
Can you tell me how to save the data in a file as a structured table using formatting tools?


My code above does save the data into a file. What's the issue - is a different file format required?
Topic archived. No new replies allowed.