-2

I'm reading in a file that is a question pool that has the type of question, chapter, how many points it is worth, the question and the answer. This bit of code is checking to see if the min and max chapters(from user input) are in range(from a file of unknown size). I know that it adds an extra line at the end of the vector, which is causing the error, but how can I fix it? The code is:

void checker(int min, int max, string file) {

        ifstream myfile;
        string line;
        vector<int> numlist;

        myfile.open(file);
        while (myfile.is_open()) {
            if (!getline(myfile, line)) {
                break;
            } else {
                vector<string> chap = split_string(line);
                int chapter = str2int(chap[2]);
                numlist.push_back(chapter); //This is where the error is. Makes vector go out of range.
            }
        }

        int small = 1000;
        int large = 0;
        for (size_t i = 0; i < numlist.size(); i++) {
            if (numlist[i] < small) {
                small = numlist[i];
            }
        }
        for (size_t i = 0; i < numlist.size(); i++) {
            if (numlist[i] > large) {
                large = numlist[i];
            }
        }
        if (min > max) {
            cout
                << "Error: Please enter a number lower than or equal to the maximum chapter: "
                << endl;
            cin >> min;
            cout << endl;
        } else if (min < small) {
            cout
                << "Error: Please enter a number bigger than or equal than the minimum chapter ("
                << small << "): " << endl;
            cin >> min;
            cout << endl;
        } else if (max > large) {
            cout
                << "Error: Please enter a number bigger than or equal than the maximum chapter ("
                << large << "): " << endl;
            cin >> max;
            cout << endl;
        }
        myfile.close();
}
johnreeves
  • 55
  • 1
  • 1
  • 8
  • Go out of range? A `push_back` will expand the vector. You are not providing us with exact error information. – StoryTeller - Unslander Monica Nov 12 '13 at 00:34
  • 1
    Only this `chap[2]`, can go out of range in the vicinity of that line. Check the size of `chap`. – StoryTeller - Unslander Monica Nov 12 '13 at 00:39
  • your `break;` statement should be `return;` or you could have a big mess. – vis.15 Nov 12 '13 at 00:49
  • The size of chap can be any number, which is why I had the push_back. – johnreeves Nov 12 '13 at 01:01
  • 'pa3.exe' (Win32): Loaded 'C:\Windows\SysWOW64\msctf.dll'. Cannot find or open the PDB file. Debug Assertion Failed! Program: C:\Windows\system32\MSVCP110D.dll File: c:\program files (x86)\microsoft visual studio 11.0\vc\include\vector Line: 1140 Expression: vector subscript out of range For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. This is the actual error message – johnreeves Nov 12 '13 at 01:02

2 Answers2

0

Its telling you that ‘chap‘ doesn't have 3 elements:

str2int(chap[2]);

You should run under the debugger to see what chap looks like, if you are using Visual Studio hit F11 to step into main.

--- Edit ---

This appears to be your problem code:

            vector<string> chap = split_string(line);
            int chapter = str2int(chap[2]);

if split_string returns a vector with less than 3 elements, the line

            int chapter = str2int(chap[2]);

is invalid. The executable will misreport the exact location of the crash when you run the executable outside the debugger because of the way the checks are implemented.

What you need to do is:

std::vector<std::string> chap = split_string(line);
if(chap.size() > 2) {
    int chapter = str2int(chap[2]);
    numlist.push_back(chapter);
}

or possibly

if (!line.empty()) {
    std::vector<std::string> chap = split_string(line);
    if (chap.size() > 2) {
        int chapter = str2int(chap[2]);
        numlist.push_back(chapter);
    }
}
kfsone
  • 23,617
  • 2
  • 42
  • 74
  • This takes element 2 from the line being read(which is the chapter number of the question). It works fine. – johnreeves Nov 12 '13 at 01:26
  • 1
    You took the time to write a rebuttal rather than run the code in a debugger? Good luck. – kfsone Nov 12 '13 at 07:40
  • That's because I tested it repeatedly in the debugger before posting this question. I know what that bit of code does. – johnreeves Nov 12 '13 at 14:03
  • When it goes past the last line in the file(all there is is an empty string) and int chapter tries to get the element, it gets nothing since there is nothing. So you are right in that 'chap' doesn't have 3 elements, because the empty string doesn't have any elements. But the **empty string** is the problem. – johnreeves Nov 12 '13 at 15:01
  • So change the `else` to `else if (!line.empty())` and before you do the `chap[2]` test that `line.size() > 2` or `line.size() == 3` – kfsone Nov 12 '13 at 18:11
  • You are correct except **the line can be any size**. After I finish turning in my assignment at midnight, I'll post the answer. – johnreeves Nov 12 '13 at 23:04
  • Sorry, I mean `chap`. Your code says `chap[2]`, without checking there are 3 elements. That's your problem. The solution is to check that `chap` contains > 2 elements before trying to execute those steps. Unless I am not getting what your actual question was. The error is not on the push_back line. Run time crash reporting can sometimes be misleading like that. – kfsone Nov 12 '13 at 23:31
0
void checker(int min, int max, string file) {

    ifstream myfile;
    string line;
    vector<int> numlist;

    myfile.open(file);
    while (!myfile.eof()) {
        if (!getline(myfile, line)) {
            break;
        } else if(line!="") {
            vector<string> chap = split_string(line);
            int chapter = str2int(chap[2]);
            numlist.push_back(chapter);
        }
    }
//other code cut out because it was not important

I just turned in this code with my assignment and it worked! chap[2] is the third element of a line from a file that was read in. There are many lines in the file that were (with help from other functions and classes) turned into their own vector. But the third element of each vector (a line read in from a file) was a number which was the chapter number (chap[2]). Now this proves that chap[2] WAS NOT the culprit. Here is a sample of a line from the file: short@1@10@In inheritance, what is the technical term for the "parent" class?@base class

johnreeves
  • 55
  • 1
  • 1
  • 8