Getting Separate Vectors from txt File

Pages: 12
Hi Guys,

I am struggling a lot at this point and could really use some help. I have the following code that works with getting data from a text file and storing it in a vector P. I need to make it so that I can get the data from the file but store it in different vectors for instance if I have the following text file:

2
1000 2 4 6 980
1000 5 90 700

I want to pull the data into my code as
P[0] = 2
P[1] = 1000 2 4 6 980
P[2] = 1000 5 90 700

I have am not sure how to make this happen. I do not want this to be pulled in as a matrix but as separate vectors that can then be manipulated with other code as necessary. Here is the code I have currently:

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
#include <iostream>
#include <cmath>
#include <vector>
#include <fstream>

using namespace std;

vector <double> get_data(){

	double value_just_read_from_file;
	vector <double> P;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
			while(input_file >> value_just_read_from_file)
			{
				P.push_back(value_just_read_from_file);
			}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "Vector_P_has_" <<P.size() << "_entries, _and_They_are : " <<endl;
	for (size_t i = 0; i < P.size(); i++)
				cout << P[i] << " ";
	cout << endl;
	return(P);
}

int main(){
	vector <double> P;
	P = get_data();
	cout<<endl;
	
}


With the data I showed above this code has output:

2 1000 2 4 6 980 1000 5 90 700

Please help me. Any suggestions at all are very very appreciated. Thanks in advance!

Also the length of the data file is not know, ie. I do not know ahead of time how many vectors are in the data file. The first input however is ALWAYS the amount of vectors that will follow. So the 2 in the first line of the data tells you that there will be two vectors.

If the first line is the number of lines that follow, could you just create a vector of vectors?

vector< vector<double> > P;

Then you can move to the next outer vector whenever you start a new line.

So the outer vector would contain the lines, and the inner vector would contain the numbers within the line.
I am not exactly sure what you mean here.

Using this data:

2
1000 2 4 6 980
1000 5 90 700

You are saying make a big vector first that reads:

2 1000 2 4 6 980 1000 5 90 700

Then split that into smaller line vectors?

Can you show what you mean by manipulating the data or showing a snippet of code that does what you are saying?
This code is by no means clean, but here's the basic premise is to read each line into a separate vector. Then have that vector stored within another vector.

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
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
#include <vector>
#include <fstream>

using namespace std;

vector < vector<double> > get_data(){

	double value_just_read_from_line;
	vector< vector<double> > P(0);
	int lineCount = -1;
	string line;
	int lengthOfLineTerminator = 2;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
		input_file >> lineCount;
		input_file.ignore(lengthOfLineTerminator);

		int index = 0;
		while (!input_file.eof()) {
			getline(input_file, line);	// read in the line from the file
			stringstream stream(line);
			vector<double> v;
			while (stream >> value_just_read_from_line) {
				v.push_back(value_just_read_from_line);
				if (input_file.peek() == '\r' || input_file.peek() == '\n')
					break;
			}
			P.push_back(v);
			index++;
		}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "Vector_P_has_" <<P.size() << "_entries, _and_They_are : " <<endl;
	for (size_t i = 0; i < P.size(); i++) {
		cout << "Vector " << i << ": " << endl;
		vector<double> vec = P[i];
		for (size_t j = 0; j < vec.size(); j++)
				cout << P[i][j] << " ";
		cout << endl;
	}
	cout << endl;
	return(P);
}

int main(){
	vector < vector<double> > P;
	P = get_data();
	cout<<endl;
	return 0;
}


Note: You may need to adjust line 16 if you're processing UNIX style files instead of Windows. I'm sure there's a way to make this more portable, but I was just hacking something together to get you an example of what I mean.
Last edited on
So now I am having trouble actually getting to and using the different vectors that are made. I am trying to access them by doing another for statement in the main along the lines of:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main(){
	vector < vector<double> > P;
	double k;
	vector <double>  T;
	P = get_data();
	for(size_t a=0; a<P.size();a++){
	T =P[a];
	for(size_t s=0;s<P[a].size();s++){
	cout << T[s] << "\t";
	}
cout<<endl;
	return 0;
}


This way I am pulling the vectors out one by one and can pass them through other functions that one at a time. This does not seem to work though. Any suggestions?
Last edited on
Nvm. I have it so I can get to the vectors individually. Thanks so much for all your help!
Ok so everything works great when I am just trying to grab the vectors. I need to do more though . I need to also find the position of each piece of the specific vectors. For instance, with data as above:

P[0] = 2
P[1] = 1000 2 4 6 980

Time for P[1][j=1...5]= 0 1 2 3 4

P[2] = 1000 5 90 700

Time for P[2][j=1...4] = 0 1 2 3

Here is how I am trying to do the time part along with my main function:

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
vector <double> get_time(){

	double value_just_read_from_line;
	vector< vector<double> > P(0);
	int lineCount = -1;
	string line;
	int lengthOfLineTerminator = 2;
	double t=0;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
		input_file >> lineCount;
		input_file.ignore(lengthOfLineTerminator);

		int index = 0;
		while (!input_file.eof()) {
			getline(input_file, line);	// read in the line from the file
			stringstream stream(line);
			vector<double> v;
 		while (stream >> value_just_read_from_line) {
				v.push_back(t++);
				if (input_file.peek() == '\r' || input_file.peek() == '\n')
					break;
			}
			P.push_back(v);
			index++;
		}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "There are " <<P.size() << " Cash Flows, they are: " <<endl;
	for (size_t i = 0; i < P.size(); i++) {
		cout << "Cashflow " << i+1 << ": " << endl;
		vector<double> vec = P[i];
		for (size_t j = 0; j < vec.size(); j++)
				cout << P[i][j] << " ";
		cout << endl;
	}
	cout << endl;
	return(P);
}

int main() {
vector < vector<double> > P;
	vector <double> time;

	vector <double>  T;
	P = get_data();
	//time = get_time();
	for(size_t a=0; a<P.size();a++){
	T =P[a];
	for(size_t s=0;s<P[a].size();s++){
	//cout << T[s] << "\t";	
		}
	cout << endl;
	}
	cout<<endl;
	return 0;
}


The idea I had was that instead of pushing the actual value of the line I am pushing t++ to represent the position of the value. This is extremely vital to the rest of my functions because for each of these vectors I need to push them through functions that are of the form

double function(vector<double>& time, vector<double>& value_of_data_at_that_time)

The problem is coming at like 43 in the return(p). There is no conversion from vector<double> to double... I don't know how to avoid this though.
Last edited on
Anyone have any ideas? Thanks in advance for any input!
Ok I have it so that the time vector is giving me an output that is consistent but it doesn't reset for each vector, it just keeps counting up...
I'm a bit confused about your requirements. By "time" do you mean "position within the vector"?

I'm doubting your need for the "time" vector at all. I believe you can just use the index.

P[1][0] will get you the double that is in the 2nd row, 1st position.
P[2][0] will get you the double that is in the 3rd row, 1st position.

Am I missing something?

Is the need to push them through a method in the form

double function(vector<double>& time, vector<double>& value_of_data_at_that_time)

a requirement that is dictated to you?


It is not a necessarily dictated requirement but it is the way I have six other functions working which I setup when I only had one vector in my input. I can change this but I absolutely do need the "time" or positions of the pieces of the vectors in their specific vectors as I said before. Example:

Input file:

100 5 5 5 5 800

200 7 7 7 800

when vector one [100 5 5 5 5 5 800] is run through my function, I NEED to have a vector [0 1 2 3 4 5] associated with it run through as well.

I then need to run the second vector [200 7 7 7 800] to run through the function and I absolutely NEED to have another vector [0 1 2 3 4] associated with it to run through as well.

This is a cash flow program that is calculating Present Values, Yield to Maturity etc...

That's why the times need to be associated with the numbers in the vectors and more specifically their positions.

It is also important to note that I do not know the exact input files. They could be 80 places long or they could be 3 terms long.

Maybe their is a better way to do this but I am not sure. Here is where I am at right now:

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
vector < vector<double> > get_data(){

	double value_just_read_from_line;
	vector< vector<double> > P(0);
	int lineCount = -1;
	string line;
	int lengthOfLineTerminator = 2;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
		input_file >> lineCount;
		input_file.ignore(lengthOfLineTerminator);

		int index = 0;
		while (!input_file.eof()) {
			getline(input_file, line);	// read in the line from the file
			stringstream stream(line);
			vector<double> v;
			while (stream >> value_just_read_from_line) {
				v.push_back(value_just_read_from_line);
				if (input_file.peek() == '\r' || input_file.peek() == '\n')
					break;
			}
			P.push_back(v);
			index++;
		}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "There are" <<P.size() << " Cash Flows, _and_They_are : " <<endl;
	for (size_t i = 0; i < P.size(); i++) {
		cout << "Cash Flow #" << i+1 << ": " << endl;
		vector<double> vec = P[i];
		for (size_t j = 0; j < vec.size(); j++)
				cout << P[i][j] << " ";
		cout << endl;
	}
	cout << endl;
	return(P);
}

vector <vector <double>> get_time(){

	double value_just_read_from_line;
	vector< vector<double> > P(0);
	int lineCount = -1;
	string line;
	int lengthOfLineTerminator = 2;
	double t=0;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
		input_file >> lineCount;
		input_file.ignore(lengthOfLineTerminator);

		int index = 0;
		while (!input_file.eof()) {
			getline(input_file, line);	// read in the line from the file
			stringstream stream(line);
			vector<double> v;
 		while (stream >> value_just_read_from_line) {
				v.push_back(t++);
				if (input_file.peek() == '\r' || input_file.peek() == '\n')
					break;
			}
			P.push_back(v);
			index++;
		}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "There are " <<P.size() << " Cash Flows, they are: " <<endl;
	for (size_t i = 0; i < P.size(); i++) {
		cout << "Time of Cashflows " << i+1 << ": " << endl;
		vector<double> vec = P[i];
		for (size_t j = 0; j < vec.size()-2; j++)
				cout << P[i][j] << " ";
		cout << endl;
	}
	cout << endl;
	return(P);
}

int main() {
vector < vector<double> > P;
	vector <vector <double> > time;

	vector <double>  CF;
	vector <double>  T;
	P = get_data();
	time = get_time();
	for(size_t a=0; a<P.size();a++){
	CF =P[a];
	T=time[a];
	for(size_t s=0;s<P[a].size();s++){
	cout << CF[s] << "\t";
	cout << T[s] << "\t";
		}


This has output:

There are 2 Cash Flows, and They are:
Cash Flow #1:
0 2 4 6 980
Cash Flow #2:
1000 5 90 700

There are 2 Cash Flows, they are:
Time of Cashflows 1:
0 1 2
Time of Cashflows 2:
5 6

0 0 2 1 4 2 6 3 980 4

100 5 5 6 90 7 700 8

Also it is important to note that the first two numbers of the cash flows that are inputed are not used in the function calculations simply due to the setup of the inputs. This is not hard for me to get around though because I have manipulated the functions to take the correct parts of the vectors.
Last edited on
Also JMJAtlanta if you want to see my full code I would be more than happy to send it to you but I do not want to put the entire thing on the forum.
Well then perhaps you simply need a function that builds the vector for you.

Something like:

1
2
3
4
5
6
vector<double> buildTimeVector(vector<double> incomingVector, vector<double>& outgoingVector) {
	for(double d = 0; d < incomingVector.size(); d++) {
		outgoingVector.push_back(d);
	}
	return outgoingVector;
}
So you'er saying make that vector as I send the P vector through each function? Or would I make that vector while making the P vectors? Or have that vector made at the beginning of each function? I am having trouble understanding how the P vectors are actually separated and in what ways I will be able to use those separate vectors that have been made.
Last edited on
Well, much of that is up to you. If you want to delay in building the time vector until you need it, then you can do it that way. If you find you're needing the time vector in a lot of different places, perhaps it would be better to build them while you build the P vector, or perhaps right after.

As for what is in the P vector. It is a vector of vectors.

Think of it with this metaphor: You have many boxes of paperclips in a drawer. In some cases, it is best to pull a box out of the drawer and do something to that box (inspect it for the number of paper clips, add some, remove some). In other cases, it may be better to take the drawer out of the cabinet and carry the entire drawer somewhere.

Getting a vector<double> from P is like taking a box of paperclips from the drawer.

Moving P around is like carrying the entire drawer of boxes of paperclips.

If your function only needs to examine 1 particular box of paperclips (in this case, the 3rd box of paperclips): examineBox(P[2]);

If your function needs to work with several different boxes of paperclips, and knows how to figure out which boxes it needs: examineDrawer(P);

I hope this metaphor helps.

Let me know if I sent you off into the weeds.
I think I understand what you mean. I want two boxes of paper clips to always travel together. I want my paper clip box of the double (ie [100 5 5 5 5 800] and my paperclip box of [0 1 2 3 4 5] to always be traveling together. Other than that I don't need to be moving the drawer around, really, ever.

I think I have an idea of where to go from here but I will likely be back with more questions in like 15 minutes ;)
For this function:
1
2
3
4
5
6
vector<double> buildTimeVector(vector<double> incomingVector, vector<double>& outgoingVector) {
	for(double d = 0; d < incomingVector.size(); d++) {
		outgoingVector.push_back(d);
	}
	return outgoingVector;
}


If I call that by buildTimeVector(P[a],T)

where P[a] is each separate vector (idea being I am only getting my time vector for each P[a] instead of trying to get an overall time vector) and T i thought would be the outgoing vector but it isn't quite working.

What exactly is returned? Does T become my time vector for P[a]?

Also is there a way to easily output a vector just so I can debug the code better?


Last edited on
Also for the get_data function above, the first number of the second line of the input file is removed from the output.

3 examples:
1.)
input:
1
10 20 30 40 50

output:
There is 1 cashflow, it is
0 20 30 40 50

2.)
input:
1
1 20 30 40 50

output:
There is 1 cashflow, it is:
20 30 40 50

3.)
input:
1
310 20 30 40 50

output:
There is 1 cashflow it is:
10 20 30 40 50

Can you explain this? I tried a few fixes but none of them are working...



Last edited on
Yes, T would become your time vector for P[a]. This should work. I haven't been keeping up with your code changes, but here's how I tested it:

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
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
#include <vector>
#include <fstream>

using namespace std;

vector < vector<double> > get_data(){

	double value_just_read_from_line;
	vector< vector<double> > P(0);
	int lineCount = -1;
	string line;
	int lengthOfLineTerminator = 2;

	ifstream input_file ("Data.txt");

	if (input_file.is_open ())
	{
		input_file >> lineCount;
		input_file.ignore(lengthOfLineTerminator);

		int index = 0;
		while (!input_file.eof()) {
			getline(input_file, line);	// read in the line from the file
			stringstream stream(line);
			vector<double> v;
			while (stream >> value_just_read_from_line) {
				v.push_back(value_just_read_from_line);
				if (input_file.peek() == '\r' || input_file.peek() == '\n')
					break;
			}
			P.push_back(v);
			index++;
		}
	}
	else
			cout << "Input_file_Data.txt_does_not_exist_in_PWD" << endl;

	cout << "Vector_P_has_" <<P.size() << "_entries, _and_They_are : " <<endl;
	for (size_t i = 0; i < P.size(); i++) {
		cout << "Vector " << i << ": " << endl;
		vector<double> vec = P[i];
		for (size_t j = 0; j < vec.size(); j++)
				cout << P[i][j] << " ";
		cout << endl;
	}
	cout << endl;
	return(P);
}

vector<double> buildTimeVector(vector<double> incomingVector, vector<double>& outgoingVector) {
	for(double d = 0; d < incomingVector.size(); d++) {
		outgoingVector.push_back(d);
	}
	return outgoingVector;
}

double function(vector<double>& time, vector<double>& value_of_data_at_that_time) {
	for(int i = 0; i < time.size(); i++)
		cout << "For position " << time[i] << " the vaule is " << value_of_data_at_that_time[i] << endl;
	return 0;
}

int main(){
	vector < vector<double> > P;
	P = get_data();
	for(int i = 0; i < P.size(); i++) {
		vector<double> time;
		buildTimeVector(P[i], time);
		function(time, P[i]);
	}
	cout<<endl;
	return 0;
}
Pages: 12