Problem with Vector Subscript Out of Range

Mar 21, 2021 at 1:32pm
I'm doing the following block of code to simply read a .csv file of 11 columns and 10 rows. The aim is to perform an analysis on the data in each row, so I wanted to separate each data point and assign their values to variables in loops. This is the 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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
	ifstream inputFile;
	inputFile.open("DummyData.csv");

	while (inputFile.good())
	{
		string line;
		vector<string> v;
		getline(inputFile, line);

		stringstream ss(line);

		while (ss.good())
		{
			string temp;
			getline(ss, temp, ',');
			v.push_back(temp);
		}

		string empcode;
		int basic1, hra1, spl1, lta1, conv1, supann1, nps1, pf1, grat1, varpay1;

		empcode = v[0];
		basic1 = stoi(v[1]);
		hra1 = stoi(v[2]);
		spl1 = stoi(v[3]);
		lta1 = stoi(v[4]);
		conv1 = stoi(v[5]);
		supann1 = stoi(v[6]);
		nps1 = stoi(v[7]);
		pf1 = stoi(v[8]);
		grat1 = stoi(v[9]);
		varpay1 = stoi(v[10]);

		cout << basic1 << " " << hra1 << " " << spl1 << " " << lta1 << " " << conv1 << " " << supann1 << " " << nps1 << " ";
		cout << pf1 << " " << grat1 << " " << varpay1 << "\n";
	}

	return 0;

}


When debugging, this is showing a Vector Subscript Out of Range error. What am I doing wrong? How do I rectify this?
Mar 21, 2021 at 1:39pm
By calling v[0] through v[10], you are making the assumption that the vector will ALWAYS successfully push_back 11 elements into it, without any room for error.

When debugging, check the size of your vector v before line 32. What does it say the size of the vector (alternatively, if dealing with STL containers while debugging is too annoying, just print the v.size() here and see).

If you showed an example of your csv file, we could more than likely tell you where the issue is.

For example, what if your file ends with a newline (for example, as is "proper" in a *nix philosophy)? Your call to getline will succeed on line 18, but your line might be empty. What happens then?
Last edited on Mar 21, 2021 at 1:44pm
Mar 21, 2021 at 1:47pm
Thanks for this. I checked the v.size() bit and noticed that even though there are only 10 rows of data, the size was showing for 11 rows. For context, I have now removed one column from my raw data set, making it 10 columns. So the size should come 10 and should show 10 times. Instead, I am getting an 11th extra instance where the size is 1. I don't understand why this is happening.

The raw csv data is a table of numbers:

600000 510000 240000 50000 50000 0 60000 72000 28846 284267
500000 425000 175000 41667 41667 75000 0 60000 24038 236889
450000 382500 180000 37500 37500 0 45000 54000 21635 213200
350000 297500 122500 29167 29167 52500 0 42000 16827 165823
550000 467500 220000 45833 45833 0 55000 66000 26442 260578
625000 531250 218750 52083 52083 93750 0 75000 30048 296111
475000 403750 190000 39583 39583 0 47500 57000 22837 225045
330000 280500 115500 27500 27500 49500 0 39600 15865 156347
295000 250750 118000 24583 24583 0 29500 35400 14183 139765
585000 497250 204750 48750 48750 87750 0 70200 28125 277160
Mar 21, 2021 at 1:49pm
Post your exact csv file contents. Preferably within [output] and [/output] tags. If it's CSV, I would expect there be commas. And tell us whether or not the last line is empty (i.e. whether or not the file ends with a newline).
Last edited on Mar 21, 2021 at 1:54pm
Mar 21, 2021 at 1:51pm
How do I do that? I'm new to the forum so not sure how to attach or add requisite files and formats.
Last edited on Mar 21, 2021 at 1:52pm
Mar 21, 2021 at 1:53pm
Just paste the text of the file here, around between the text [output] and [/output]. You can also use pastebin.com.

In general, you should NOT be looping on <stream>.good(). You should be looping on the actual proper extraction of data.

So, for example, your outer loop would loop on:
1
2
3
4
while (getline(inputFile, line))
{

}


Your inner loop can loop on:
 
while (getline(ss, temp, ','))


After your inner loop, if your v.size() is < 11, then print some flagrant error to the user and return, because something went wrong.
Last edited on Mar 21, 2021 at 1:57pm
Mar 21, 2021 at 1:58pm
The .csv text looks like this:

600000,510000,240000,50000,50000,0,60000,72000,28846,284267
500000,425000,175000,41667,41667,75000,0,60000,24038,236889
450000,382500,180000,37500,37500,0,45000,54000,21635,213200
350000,297500,122500,29167,29167,52500,0,42000,16827,165823
550000,467500,220000,45833,45833,0,55000,66000,26442,260578
625000,531250,218750,52083,52083,93750,0,75000,30048,296111
475000,403750,190000,39583,39583,0,47500,57000,22837,225045
330000,280500,115500,27500,27500,49500,0,39600,15865,156347
295000,250750,118000,24583,24583,0,29500,35400,14183,139765
585000,497250,204750,48750,48750,87750,0,70200,28125,277160


There is an extra line here.

For the looping, if I use your code, I will have to declare line and temp outside the loops first. Currently they are being declared inside the loop. Should I move the variables out of their respective loops then?
Mar 21, 2021 at 2:00pm
Yes, but your bigger issue is that you only have 10 columns, yet you are trying to extract 11 distinct things from each line. This doesn't make sense.

And for the extra line at the end, you should check if v.size() < 11, and if so, then break out of your loop, because it wasn't able to extract all the data it needed.
Last edited on Mar 21, 2021 at 2:02pm
Mar 21, 2021 at 2:03pm
I mentioned that I had removed a column. So I removed the variable empcode (which was the first column previously) and shifted all other v[] to 0 to 9. That makes 10 columns.

Also, I just made my loop conditions based on your input, and now the output for v.size() is:

5
5
5
5
5

So its only reading 5 rows and 5 columns. Not sure why this is occurring.
Last edited on Mar 21, 2021 at 2:04pm
Mar 21, 2021 at 2:07pm
Let's start over.

From your original code, and your original CSV file, change:
1
2
3
4
5
6
		while (ss.good())
		{
			string temp;
			getline(ss, temp, ',');
			v.push_back(temp);
		}


to

1
2
3
4
5
6
7
8
9
10
11
12
		while (ss.good())
		{
			string temp;
			getline(ss, temp, ',');
			v.push_back(temp);
		}
		
		if (v.size() < 11)
		{
			// this line did not contain enough data to use; possibly end of file
			continue;
		}


What happens?
Last edited on Mar 21, 2021 at 2:13pm
Mar 21, 2021 at 2:15pm
I've updated the 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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
	ifstream inputFile;
	inputFile.open("DummyData.csv");

	string line;
	
	while (getline(inputFile,line))
	{
		vector <string> v;
		getline(inputFile, line);

		stringstream ss(line);
		string temp;

		while (getline(ss, temp, ','))
		{
			getline(ss, temp, ',');
			v.push_back(temp);
		}

		if (v.size() < 11)
		{
			continue;
		}

		int vector_size = v.size();
		cout << vector_size << "\n";

		int basic_c, hra_c, spl_c, lta_c, conv_c, supann_c, nps_c, pf_c, grat_c, varpay_c;

		basic_c = stoi(v[0]);
		hra_c = stoi(v[1]);
		spl_c = stoi(v[2]);
		lta_c = stoi(v[3]);
		conv_c = stoi(v[4]);
		supann_c = stoi(v[5]);
		nps_c = stoi(v[6]);
		pf_c = stoi(v[7]);
		grat_c = stoi(v[8]);
		varpay_c = stoi(v[9]);
	}

	return 0;

}


No output is coming anymore.
Mar 21, 2021 at 2:15pm
There are only 10 elements per line, not 11! I suspect there's no employee 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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
	ifstream inputFile("DummyData.csv");

	if (!inputFile)
		return (cout << "Cannot open input file\n"), 1;

	for (string line; getline(inputFile, line); ) {
		vector<string> v;
		istringstream ss(line);

		for (string temp; getline(ss, temp, ','); )
			v.push_back(temp);

		if (v.size() == 10) {	// ONLY 10 ELEMENTS NOT 11
			//const string empcode {v[0]};
			const int basic1 {stoi(v[0])};
			const int hra1 {stoi(v[1])};
			const int spl1 {stoi(v[2])};
			const int lta1 {stoi(v[3])};
			const int conv1 {stoi(v[4])};
			const int supann1 {stoi(v[5])};
			const int nps1 {stoi(v[6])};
			const int pf1 {stoi(v[7])};
			const int grat1 {stoi(v[8])};
			const int varpay1 {stoi(v[9])};

			cout << basic1 << " " << hra1 << " " << spl1 << " " << lta1 << " " << conv1 << " " << supann1 << " " << nps1 << " ";
			cout << pf1 << " " << grat1 << " " << varpay1 << "\n";
		} else
			cout << "Only " << v.size() << " elements\n";
	}
}



600000 510000 240000 50000 50000 0 60000 72000 28846 284267
500000 425000 175000 41667 41667 75000 0 60000 24038 236889
450000 382500 180000 37500 37500 0 45000 54000 21635 213200
350000 297500 122500 29167 29167 52500 0 42000 16827 165823
550000 467500 220000 45833 45833 0 55000 66000 26442 260578
625000 531250 218750 52083 52083 93750 0 75000 30048 296111
475000 403750 190000 39583 39583 0 47500 57000 22837 225045
330000 280500 115500 27500 27500 49500 0 39600 15865 156347
295000 250750 118000 24583 24583 0 29500 35400 14183 139765
585000 497250 204750 48750 48750 87750 0 70200 28125 277160


Mar 21, 2021 at 2:30pm
I'm constantly getting the following errors when debugging:

invalid_argument at memory location 0x00FEF528

The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

Also, when running this, the first basic_c value is ALWAYS coming to 0 even though its actually 600000. I'm beyond stumped at this point since every fix seems to be creating fresh errors in different places.

This is the fresh 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
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
	ifstream inputFile;
	inputFile.open("DummyData.csv");

	if (!inputFile)
	{
		return (cout << "Cannot open file. Please try again.\n"), 1;
	}

	for (string line; getline(inputFile,line); )
	{
		vector <string> v;
		istringstream ss(line);

		for (string temp; getline(ss, temp, ','); )
		{
			v.push_back(temp);
		}

		if (v.size() == 10)
		{
			const int basic_c{ stoi(v[0]) };
			const int hra_c{ stoi(v[1]) };
			const int spl_c{ stoi(v[2]) };
			const int lta_c{ stoi(v[3]) };
			const int conv_c{ stoi(v[4]) };
			const int supann_c{ stoi(v[5]) };
			const int nps_c{ stoi(v[6]) };
			const int pf_c{ stoi(v[7]) };
			const int grat_c{ stoi(v[8]) };
			const int varpay_c{ stoi(v[9]) };

			cout << basic_c << "\n" << varpay_c << "\n";
		}
	}

	return 0;
}


EDIT: I'm dumb. The issue was popping up because of the file type of my .csv. I changed it from CSV UTF-8 to just CSV and it seems to be working fine. Thanks so much guys for putting up with my code!
Last edited on Mar 21, 2021 at 2:37pm
Topic archived. No new replies allowed.