String Subscript Out of Range Error... Please help me

i wrote a bool function to check if inputted command is in a valid format
command is valid if (two alphabets: airlinecode)(digits 0 to 999:flight number)(+ or -) (digit 0 to 999: arrival minute different than the scheduled time)
for example:
valid form: aa1+1 aa132-124 and also aa142-3ua32-0sw-231
invalid form: a1-1 aa-3-333 aa4*324 aa1111-1

when i run the program, string subscript out of range error message pops up
what should i fix??

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
 bool isWellFormedAirportString(string s) {
	bool result = true;
	for (size_t i = 0; i < s.size(); i++) {
		if (isalpha(s[i])) {						//alpha only for the airline code. has to be 2 letters.
			if ((i == 0 && i + 1<s.size() && isalpha(s[i + 1])) || (i > 0 && isalpha(s[i - 1])) || (i + 1<s.size() && i >= 0 && isalpha(s[i + 1]))) {      //an alphabet next to another alphabet
				string airline;
				airline += s[i];			//airline= letter at i
				if (i + 1<s.size() && i > 0 && isalpha(s[i - 1]) && isalpha(s[i + 1])) continue;  //letter in the middle of a letter string
				if (i + 1<s.size() && isalpha(s[i + 1])) {		//the first letter of airline code
					while (isalpha(s[i + 1])) {
						airline += s[i + 1];
						i++;
					}
					if (airline.size() != 2) result = false;
				}
				if (i > 0 && isalpha(s[i - 1])) {	//last letter ot airliine code
					while (isalpha(s[i - 1]) && i >= 1) {
						airline += s[i - 1];		//not actual airline code. just for the size.
						i--;
					}

					if (airline.size() != 2) result = false;
				}
			}
			if ((i > 0 && !isalpha(s[i - 1]) && !isdigit(s[i - 1])) || (i + 1<s.size() && !isalpha(s[i + 1]) && !isdigit(s[i + 1]))) result = false;     //an alphabet next to a symbol
		}

		if (isdigit(s[i])) {				// either flight number or a minute

			if (i == 0 || i == 1) result = false;  //first and second values shouldn't be a number
			if ((i > 0 && isdigit(s[i - 1])) && i + 1<s.size() && isdigit(s[i + 1])) continue; //a number in the middle of a number series
			if ((i > 0 && isalpha(s[i - 1])) && i + 1<s.size() && isdigit(s[i + 1])) {		//first number of flight number
				string flightNum;
				flightNum = s[i];
				while (i + 1<s.size() && isdigit(s[i + 1])) {
					flightNum += s[i + 1];
					i++;
				}
				if (flightNum.size() == 0 || flightNum.size() > 3) result = false;  //flight number should be 0~999
			}

			if ((i > 0 && isdigit(s[i - 1])) && i + 1<s.size() && !isdigit(s[i + 1]) && !isalpha(s[i + 1])) { //last number of flight number
				string flightNum;
				flightNum = s[i];
				while (i > 0 && isdigit(s[i - 1])) {
					flightNum += s[i - 1];	//not the actual flight number. just for the size
					i--;
				}
				if (flightNum.size() == 0 || flightNum.size() > 3) result = false;  //flight number should be 0~999
			}
			if (i > 0 && isalpha(s[i - 1]) && i + 1<s.size() && !isalpha(s[i + 1]) && !isdigit(s[i + 1])) continue;	//flight Number is one digit = valid


			if (i > 0 && !isdigit(s[i - 1]) && !isdigit(s[i - 1])) {	//minute value
				string minute;
				minute = s[i];
				while (i + 1<s.size() && isdigit(s[i + 1])) {
					minute = +s[i + 1];
					i++;
				}
				if (minute.size() == 0 || minute.size() > 3) result = false;
			}
		}

		if (!isdigit(s[i]) && !isalpha(s[i])) {	//symbol
			if (i == 0 || i == 1 || i == 2) result = false;
			if (i > 0 && !isdigit(s[i - 1]) && i + 1<s.size() && !isdigit(s[i + 1])) result = false;
		}

		if (isalpha(s[i]) && i + 1<s.size() && isalpha(s[i + 1])) {		//valid airline code, i= position of first letter of the airline code.
			tolower(s[i]);
			tolower(s[i + 1]);			//converting letters to lowercase

			if (s[i] == 'a') {	//first letter =a
				if (s[i + 1] == 'a' || s[i + 1] == 'l') result = true;
			}
			if (s[i] == 'd') {	//first letter = d
				if (s[i + 1] == 'l') result = true;
			}
			if (s[i] == 'u') {	//first letter = u
				if (s[i + 1] == 'a') result = true;
			}
			if (s[i] == 's') {		//first letter = s
				if (s[i + 1] == 'w') result = true;
			}
			if (s[i] == 'v')	//first letter = v
				if (s[i + 1] == 'a') result = true;
		}
		else result = false;
	}

	return (result);
}
Last edited on
somewhere in that you are out of bounds. something like s[toobig or negative].

the ugly way to do it is print your string sizes and all the computed indices used. If it comes to that, the approach works.

ideally the compiler error or running in debug mode will show the error or at least the line of the error.

s[i + 1]
When i is at the last iteration (i = size - 1), the above code will evaluate to s[size], which is invalid, as indices range from 0 to size - 1.
I tried to follow your code to find the bug, but it was really complicated, so I've tried to start from a different point of view. I hope it could be helpful.
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
#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::string;

bool isWellFormedAirportString(std::string s);

int main()
{
    std::vector<string> v {"aa1+1", "aa132-124", "aa142-3", 
                            "ua32-0", "sw-231", "a1-1", 
                            "aa-3-333", "aa4*324", "aa1111-1"};
    for(auto test : v) {
        cout << "isWellFormedAirportString(\"" << test
                << "\") returned " 
                << isWellFormedAirportString(test) << endl;
    }

    return 0;
}

/* ================================================================= 
 * Valid codes:
 *   2 alphabets: airlinecode
 * + digits 0 to 999: flight number
 * (+ or -) digit 0 to 999: arrival minute different than 
 *              the scheduled time
 * valid form: aa1+1, aa132-124, aa142-3ua32-0sw-231
 * invalid form: a1-1, aa-3-333, aa4*324, aa1111-1
 * ================================================================= */
bool isWellFormedAirportString(std::string s) {

    // There can't be less then 
    //     2 letters (airline code)
    //   + 1 digit (flight number)
    //   + 1 character between + or -
    //   + 1 digit (minutes of differences)
    // 5 characters in s.
    if(s.size() < 5)
        return false;

    // Let's check if first 2 characters are 2 letters
    if (!isalpha(s.at(0)) || !isalpha(s.at(1))) {
        return false;
    } else {
        // We don't need the first 2 characters any more.
        // (let's keep things simple) :-) 
        // Note: could also be written s.erase(2), since the first
        //       parameter default to 0.
        s.erase(0, 2);
    }

    // Let's search for a '+' or a '-' now.
    string::size_type plusminus(string::npos);
    if( (plusminus=s.find_first_of("+-")) != string::npos ) {
        // Ok, somewhere there is a '+' or a '-', but it must
        // not be beyond the 3rd character.
        // Let's assume now s starts with 3 digits, in positions
        // 0, 1, 2. plusminus should not be > 3.
        if(plusminus > 3) {
            return false;
        } else {
            // Now we need to check if in s[0] to s[plusminus -1]
            // there are digits.
            for(string::size_type i(0); i < plusminus -1; i++) {
                if(!isdigit(s.at(i)))
                    return false;
            }
        }
    } else {
        // We get here if find_first_of returns npos, that means
        // there isn't neither a '+' nor a '-' in s, 
        // so s is invalid.
        return false;
    }

    // If we get here, we know that now s starts with 1, 2 or 3
    // digits followed by a '+' or a '-'.
    // The position of the '+' or the '-' is stored in plusminus.
    // We don't need any of them any more.
    s.erase(plusminus); // ...or s.erase(0, plusminus);

    // Ok, now we must check if there is any character left
    // (the '+' or the '-' could have not be followed by
    // any other character) end if they are digits.
    if(s.empty())
        return false;
    for(string::size_type i(0); i < s.size(); i++) {
        if(!isdigit(s.at(i)))
            return false;
    }

    // Wow! We get to the end...
    // We can safely infer that s is valid.
    return true;
}

Ops! There's an error in my code, since near the end it doesn't check if there are no more then 3 characters left.
so the statement
if(s.empty())
needs to become
if(s.empty() || s.size() > 3)
...sorry :$...
...and another, I'm afraid...
after if( (plusminus=s.find_first_of("+-")) != string::npos ) { we should check if find_first_of() returned 0, that would mean there isn't any "flight number".
So we need something like:
1
2
3
if(plusminus < 1) {
    return false;
}

My bad, I should have paid more attention.
Topic archived. No new replies allowed.