Issue with vector being out of range

I have a function which is supposed to write all the data from a txt file to a vector, and it comes up with the error, "Debug assertion failed. C++ vector subscript out of range". I'm not too sure why this is happening. I decided to do this because the file is an unknown size. If there is a better way to do this, that would help. Or, if there is an error, it would be good to know, thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void getUserPassData() {
	int count = 1;
	cout << "Loading...\n";
	ifstream userInFile;
	ifstream passInFile;

	userInFile.open("data\\usernameList.txt"); //Opens the username file
	passInFile.open("data\\passwordList.txt"); //Opens the password file

	//Cycles through the files, putting them into an array
	while (!userInFile.eof()) {
		for (int i = 0; i < count; ++i) {
			userInFile >> usernames[i];
			passInFile >> passwords[i];
		}
		++count;
	}
	userInFile.close();
	passInFile.close();
}
If you need to see more than just this function, I can post more.
Unlike associative containers, std::vector is not automatically resized when using the subscript operator to access element that doesn't exist.

You can use the resize function to set the size of the vector.
http://www.cplusplus.com/reference/vector/vector/resize/

You can also use push_back to add elements to the end of the vector (increasing the size by one).
http://www.cplusplus.com/reference/vector/vector/push_back/
Oh, I see, thank you!
So I believe I fixed that error, but now I have a new one. Its not a compiler error, just that the code isn't doing what I want. It seems that I implemented the .eof() function wrong, or I just do not understand the logic of it, because I included some "Loading..." tests to see whether it makes it through the function, and it just infinitely loops. Heres the current status of 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
void getUserPassData() {
	int count = 1;
	cout << "Loading...\n";
	ifstream userInFile;
	ifstream passInFile;

	userInFile.open("data\\usernameList.txt"); //Opens the username file
	passInFile.open("data\\passwordList.txt"); //Opens the password file

	//Cycles through the files, putting them into an array
	//Two count variables save memory by eliminating the need to pass through all prior lines in for loop
	while (userInFile.eof() == false) {
		for (int i = 0; i < count; ++i) {
			usernames.resize(usernames.size() + 1);
			passwords.resize(passwords.size() + 1);

			getline(userInFile, usernames[i]);
			getline(passInFile, passwords[i]);
			cout << "Loading...";
		}
		++count;
	}
	userInFile.close();
	passInFile.close();
	cout << "Successfully loaded vector data...";
}
usernames and passwords are not defined within the function but I'm guessing they're std::vector<std::string> and that the input file has username and password on alternate lines? Rather than manage two vectors it'd be far easier to use a struct with appropriate overloads of the ctor (and insertion << operator).
Here you can also reserve vector capacity before starting the file read to avoid interim re-allocations:
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 <string>
#include <vector>
#include <fstream>

struct Login
{
    std::string m_userName;
    std::string m_password;

    Login() {}
    Login(const std::string& userName, const std::string& password)
    : m_userName(userName), m_password(password) {}
};
std::ostream& operator << (std::ostream& os, const Login& log)
{
    os << log.m_userName << " " << log.m_password << '\n';
    return os;
}

int main()
{
    std::ifstream inputFile("D:\\input2.txt");
    std::vector<Login> logins{};
    logins.reserve(3);//requests that vector capacity be at least enough to contain 3 Login objects
    //useful when reading in large number of objects and don't desire reallocation in between
    while(inputFile)//do some file opening checks as well
    {
        Login temp{};
        getline(inputFile, temp.m_userName);
        getline(inputFile, temp.m_password);
        if(inputFile)
        {
            logins.push_back(temp);
        }
    }
    for (const auto& elem : logins)
    {
        std::cout << elem ;
    }
}
/*
Sample text file:
John
123
Jane
456
Other
789
Sample Output:
John 123
Jane 456
Other 789
*/
Last edited on
Topic archived. No new replies allowed.