I need help reading in from/writing to files in C++

I am writing a program that reads in a list of pilots' names followed by a set of coordinates for each pilot from a file. The program takes the pilots' coordinates, converts it to an area, and then writes the pilots' names and areas to a separate file. The number of pilots in the input file can be unlimited so the program needs to keep running until all the pilots and coordinates converted to areas have been written to the output file. Right now the program only writes one line to the output file. What am I doing wrong?

Here is what the input file looks like:

Jim 4,10 9,7 11,2 2,2 4,10
Sam 2,2 2,-2 -2,-2 -2,2 2,2
Marco 5,5 5,-5 -5,-5 -5,5 5,5
Polo 7,3 6,-9 -1,-2 -4,4 7,3

This is all I am getting for the output:

Jim 45.50

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
94
95
96
97
98
99
100
101
102
103
#include <fstream>
#include <string>
#include <iomanip>
#include <stdlib.h>
using namespace std;

void read(static ifstream &, string &, float[], float[]);
float calculate(float[], float[]);
void write(static ofstream &, string, float);

int main()
{
	ifstream input;
	input.open("pilot_routes.txt");

	ofstream output;
	output.open("pilot_areas.txt");

	string name;
	float area;
	float numbers_x[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	float numbers_y[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  
	while (input)
	{
		read(input, name, numbers_x, numbers_y);
		area = calculate(numbers_x, numbers_y);
		write(output, name, area);
	}

	output.close();

	return 0;
}

void read(static ifstream & input, string & pilot, float x[], float y[])
{
	int i;
	char comma;

	input >> pilot;

	for (i = 0; i < 15; i++)
	{
		input >> x[i];
		input >> comma;
		input >> y[i];
	}
}

float calculate(float x[], float y[])
{
	float size, result, num1, num2, num3, num4, num5, num6, num7, num8, num9, num10, num11, num12, num13, num14;
	int i;

	for (i = 0; i < 14; i++)
	{
		result = (x[i] * y[i + 1]) - (y[i] * x[i + 1]);

		if (i == 0)
			num1 = result;
		else if (i == 1)
			num2 = result;
		else if (i == 2)
			num3 = result;
		else if (i == 3)
			num4 = result;
		else if (i == 4)
			num5 = result;
		else if (i == 5)
			num6 = result;
		else if (i == 6)
			num7 = result;
		else if (i == 7)
			num8 = result;
		else if (i == 8)
			num9 = result;
		else if (i == 9)
			num10 = result;
		else if (i == 10)
			num11 = result;
		else if (i == 11)
			num12 = result;
		else if (i == 12)
			num13 = result;
		else
			num14 = result;
	}

	result = (num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 + num10 + num11 + num12 + num13 + num14) / 2;

	if (result >= 0)
		size = result;
	else
		size = result * -1;

	return size;
}

void write(static ofstream & output, string fighter, float patrol_area)
{
	output << fighter << "\t" << setprecision(2) << showpoint << fixed << patrol_area << endl;
}
Last edited on
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <fstream>
#include <string>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

void read(static ifstream & input, string & pilot, vector<float> &x, vector<float> &y);
float calculate(vector<float> x, vector<float> y);
void write(static ofstream &, string, float);

int main()
{
	ifstream input;
	input.open("pilot_routes.txt");

	ofstream output;
	output.open("pilot_areas.txt");

	string name;
	float area;
	vector<float> numbers_x;
	vector<float> numbers_y;

        // while not end of file
	while (!input.eof())
	{		
		numbers_x.clear();
		numbers_y.clear();

		read(input, name, numbers_x, numbers_y);	

		std::cout << "pilot " << name << std::endl;

		for (int i = 0; i < numbers_x.size(); i++)
		{			
			std::cout << "x " << numbers_x[i] << ", y " << numbers_y[i] << std::endl;
		}

                // just adjust 
		area = calculate(numbers_x, numbers_y);

		write(output, name, area);		
	}
	

	output.close();

	int x;
	cin >> x;
	return 0;
}

void read(static ifstream & input, string &pilot, vector<float> &x, vector<float> &y)
{
       // get current line
	std::getline(input, pilot);
        
	std::string delimiter = " ";
	size_t pos = 0;
	std::string token;

	std::vector<string> results;

        // parse the current line
	while ((pos = pilot.find(delimiter)) != std::string::npos) {
		token = pilot.substr(0, pos);
		results.push_back(token);
		pilot.erase(0, pos + delimiter.length());
	}
	results.push_back(pilot);

	delimiter = ",";
	pos = 0;

	std::vector<float> num;

        // split the x and y values
	for (auto i : results)
	{
		while ((pos = i.find(delimiter)) != std::string::npos)
		{
			token = i.substr(0, pos);
			x.push_back(::atof(token.c_str()));
			i.erase(0, pos + delimiter.length());
		}
		y.push_back(::atof(i.c_str()));
	}

	pilot = results[0];	

}

float calculate(vector<float> x, vector<float> y)
{
          //calculates values but not the same as yours
	float result,size;

	for (int i = 0; i < x.size() - 1; i++)
	{
		result = (x[i] * y[i + 1]) - (y[i] * x[i + 1]);
	}	

	if (result >= 0)
		size = result;
	else
		size = result * -1;

	return size;
}

void write(static ofstream & output, string fighter, float patrol_area)
{
	output << fighter << "\t" << setprecision(2) << showpoint << fixed << patrol_area << endl;
}
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <fstream>
#include <string>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

void read(static ifstream & input, string & pilot, vector<float> &x, vector<float> &y);
float calculate(vector<float> x, vector<float> y);
void write(static ofstream &, string, float);

int main()
{
	ifstream input;
	input.open("pilot_routes.txt");

	ofstream output;
	output.open("pilot_areas.txt");

	string name;
	float area;
	vector<float> numbers_x;
	vector<float> numbers_y;

	while (!input.eof())
	{		
		numbers_x.clear();
		numbers_y.clear();

		read(input, name, numbers_x, numbers_y);	

		std::cout << "pilot " << name << std::endl;

		for (int i = 0; i < numbers_x.size(); i++)
		{			
			std::cout << "x " << numbers_x[i] << ", y " << numbers_y[i] << std::endl;
		}

		for (int i = 0; i < 10; i++)
		{
			numbers_x.push_back(0);
			numbers_y.push_back(0);
		}

		std::cout << "numbers " << numbers_x.size();

		area = calculate(numbers_x, numbers_y);
		write(output, name, area);		
	}
	

	output.close();

	int x;
	cin >> x;
	return 0;
}

void read(static ifstream & input, string &pilot, vector<float> &x, vector<float> &y)
{
	std::getline(input, pilot);
	//std::cout << name << std::endl;

	std::string delimiter = " ";
	size_t pos = 0;
	std::string token;

	std::vector<string> results;

	while ((pos = pilot.find(delimiter)) != std::string::npos) {
		token = pilot.substr(0, pos);
		results.push_back(token);
		pilot.erase(0, pos + delimiter.length());
	}
	results.push_back(pilot);

	delimiter = ",";
	pos = 0;

	std::vector<float> num;

	for (auto i : results)
	{
		while ((pos = i.find(delimiter)) != std::string::npos)
		{
			token = i.substr(0, pos);
			x.push_back(::atof(token.c_str()));
			i.erase(0, pos + delimiter.length());
		}
		y.push_back(::atof(i.c_str()));
	}

	pilot = results[0];	

}

float calculate(vector<float> x, vector<float> y)
{
	float size, result, num1, num2, num3, num4, num5, num6, num7, num8, num9, num10, num11, num12, num13, num14;
	int i;

	for (i = 0; i < 14; i++)
	{
		result = (x[i] * y[i + 1]) - (y[i] * x[i + 1]);

		if (i == 0)
			num1 = result;
		else if (i == 1)
			num2 = result;
		else if (i == 2)
			num3 = result;
		else if (i == 3)
			num4 = result;
		else if (i == 4)
			num5 = result;
		else if (i == 5)
			num6 = result;
		else if (i == 6)
			num7 = result;
		else if (i == 7)
			num8 = result;
		else if (i == 8)
			num9 = result;
		else if (i == 9)
			num10 = result;
		else if (i == 10)
			num11 = result;
		else if (i == 11)
			num12 = result;
		else if (i == 12)
			num13 = result;
		else
			num14 = result;
	}

	result = (num1 + num2 + num3 + num4 + num5 + num6 + num7 + num8 + num9 + num10 + num11 + num12 + num13 + num14) / 2;

	if (result >= 0)
		size = result;
	else
		size = result * -1;

	return size;
}

void write(static ofstream & output, string fighter, float patrol_area)
{
	output << fighter << "\t" << setprecision(2) << showpoint << fixed << patrol_area << endl;
}
My first suggestion would be to read an entire line with getline() then use a stringstream to process that line:

In main():
1
2
3
4
5
6
7
	while(getline(input, line))
	{
                istringstream ins(line);
		read(ins, name, numbers_x, numbers_y);
		area = calculate(numbers_x, numbers_y);
		write(output, name, area);
	}


This will require changing your read() prototype to:
void read( istream &, string &, float[], float[]);
Note the use of an istream instead of ifstream. Also note the lack of the static specifier. With the static specifier the code shouldn't compile. Don't forget to include the proper include file for the stringstream.

What's with all those "numX" in your calculate() function? Wouldn't something like the following be simpler?

1
2
3
4
5
6
	float size, result = 0.0 ;
	int i;

	for (i = 0; i < 14; i++)
	{
		result += (x[i] * y[i + 1]) - (y[i] * x[i + 1]);


Also there only appears to be 10 sets of numbers not 15.

Last edited on
Topic archived. No new replies allowed.