While statement goes on beyond specified perameters

So I am extremely new at c++. I'm taking a 101 class on it right now.

the simplified goal of my program is to intake data from a user specified .txt file that holds info on library members, and assign each aspect of the data to a corresponding array. the data in the .txt file is formatted in a very specific way, with each library member's data represented in this order one after another:

Last Name, First Name
Member ID Borrowing Status.

Right now, my code to open the .txt file and assign the data to arrays looks like this:

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
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <math.h>

using namespace std;

//Declaration of Global Variables
fstream memberlist;
string memberfile, firstname[20], lastname[20], memberid[20], borrowingstatus[20];

void get_member_data()
{
string name, idstatus;
size_t comma, space;

for(int i=0; memberlist.good(); i++ ){
	getline(memberlist,name);
	getline(memberlist, idstatus);
	comma = name.find(",");
	lastname[i] = name.substr (0, comma);
	comma += 2;
	firstname[i] = name.substr (comma);
	space = idstatus.find(" ");
	memberid[i] = idstatus.substr (0, space);
	space += 1;
	borrowingstatus[i] = idstatus.substr (space);
	}
}

void open_member_list()
{
cout<< "Please enter the name of the member list data file: ";
getline(cin, memberfile);
memberlist.open(memberfile.c_str()); // opens the file
if (memberlist.is_open()){
	get_member_data();
	}
else
	{ // file couldn't be opened
	 cout << "Error: file could not be opened" << endl;
	 exit(EXIT_FAILURE);
	}

memberlist.close();		   
}

int main()
{
open_member_list();
cout << endl << firstname[0] << " " << lastname[0] << " " << memberid[0] << " " << borrowingstatus[0];

return 0;
}


This code compiles fine, but when i run the a.out file my output looks like this:

Please enter the name of the member list data file: memberlist.txt
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr
Abort


So you know, the memberlist.txt file I'm working with to test my program looks like this:

Smith, John Adam
123456 0
Winston Jr., James
123457 1

I did a little tweaking to see if I could find where the problem was in my code and changed it to look like this:

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
fstream memberlist;
string memberfile, firstname[20], lastname[20], memberid[20], borrowingstatus[20];

void get_member_data()
{
string name, idstatus;
size_t comma, space;

for(int i=0; memberlist.good(); i++ ){
	getline(memberlist,name);
	getline(memberlist, idstatus);
cout << name << " >>> " << idstatus << endl;
	comma = name.find(",");
	lastname[i] = name.substr (0, comma);
cout << lastname[i] << endl;
	comma += 2;
	firstname[i] = name.substr (comma);
	space = idstatus.find(" ");
	memberid[i] = idstatus.substr (0, space);
cout << memberid[i] << endl;
	space += 1;
	borrowingstatus[i] = idstatus.substr (space);
cout << borrowingstatus[i] << endl;
	}
}


and now when i run the program my output looks like:

Please enter the name of the member list data file: memberlist.txt
Smith, John Adam >>> 123456 0
Smith
123456
0
Winston Jr., James >>> 123457 1
Winston Jr.
123457
1
 >>> 123457 1

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr
Abort


What is that extra " >>> 123457 1" at the end? it seems like the while statement is trying to reuse data it already used and go on past the end of the file, and I dont know why. Any insight on the matter would be greatly appreciated.


Maybe do this:

1
2
for(int i=0; memberlist.good(); i++ ){
	if( getline(memberlist,name) || getline(memberlist, idstatus) ) break;


Checks for read errors
Putting that in didn't work, but i see what you were trying to do. Thanks to your inspiration i came up with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void get_member_data()
{
string name, idstatus, checkname, checkidstatus;
size_t comma, space;

for(int i=0; memberlist.good(); i++ ){
	checkname = name;
	checkidstatus = idstatus;
	getline(memberlist,name);
	getline(memberlist, idstatus);
	if( name == checkname || idstatus == checkidstatus) break;
	comma = name.find(",");
	lastname[i] = name.substr (0, comma);
	comma += 2;
	firstname[i] = name.substr (comma);
	space = idstatus.find(" ");
	memberid[i] = idstatus.substr (0, space);
	space += 1;
	borrowingstatus[i] = idstatus.substr (space);
	}
}


its not pretty, but its working. If anyone knows why the for statement was acting up in the first place, I'd appreciate knowing just for knowledge's sake, but otherwise case closed
Topic archived. No new replies allowed.