String subscript out of range error

I'm trying to create an ad hoc scanner that reads a calculator language.
When I execute the program, I get an error saying the following:
"Debug Assertion Failed!
...
Expression: string subscript out of range"

If I click the "Ignore" button a bunch of times, it will eventually produce the output file of my liking.

My sample input file has this written inside of it:
read A1
read A2
sum:=(A1-33)+A2*5.5
write sum
write (A1+A2)/2

sample output file looks like this:
read
A1
read
A2
Sum
:=
(
A1
-
33
)
+
A2
*
5.5
write
sum
write
(
A1
+
A2
)
/
2

but when I go to run the program, the error will stop right before the first "write" and give the error. Like I said, spamming ignore allowed the rest of it to print eventually.

I've tried looking into this problem and believe it has something to do with my string size but I'm unsure. Could anyone tell me what might be the fix here?

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

    string holder;
    fstream handling;
    ofstream output;
    int x = 0;

int main()
{
    output.open("output.txt");
    handling.open("input.txt");
	while(handling.is_open())
	{
		
		getline(handling, holder);
		cout << holder;
		if(holder[x] == 'r' && holder[x+1] == 'e')
		{
			output << "read\n";
			if(holder[x+4] == ' ')
			{
				for(int i = 5; i < (int)holder.length(); i++)
					output << holder[i];
				output << "\n";
			}
		}
		
		if(holder[x] == 'w' && holder[x+1] == 'r')
		{
			output << "write\n";
			if(holder[x+6] == 's' || holder[x+7] == 'u')
				output << "sum\n";
			else
			{
				//this loop seperates the long string of numbers and operators.
				for(int i = 6; i < (int)holder.length(); i++)
				{
					if(holder[i] == '(')
						output << "(\n";
					if(isalpha(holder[i]) != 0)
					{
						output << holder[i];
						i++;
						if(isdigit(holder[i]) != 0)
						{
							output << holder[i] << "\n";
							i++;
						}
					}
					if(holder[i] == '+' || holder[i] == '-' || holder[i] =='*' || holder[i] == '/')
						output << holder[i] << "\n";
					if(holder[i] == ')')
						output << ")\n";
					if(isdigit(holder[i]) != 0)
					{
						output << holder[i];
						if(holder[i+1] == '.')
						{
							output << ".";
							i++;
						}

						if((holder[i+1] == '+' || holder[i+1] == '-' || holder[i+1] == '*' || holder[i+1] == '/' || holder[i+1] == '(' || holder[i+1] == ')') || i+1 == holder.length())
							output << "\n";
					}
				}
			}
		}

			

		if(holder[x] == 's' && holder[x+1] == 'u')
		{
			output << "sum\n";
			if(holder[x+3] == ':' && holder[x+4] == '=')
				output << ":=\n";
			
			//this loop seperates the long string of numbers and operators.
			for(int i = 4; i < (int)holder.length(); i++)
			{
				if(holder[i] == '(')
					output << "(\n";
				if(isalpha(holder[i]) != 0)
				{
					output << holder[i];
					i++;
					if(isdigit(holder[i]) != 0)
					{
						output << holder[i] << "\n";
						i++;
					}
				}
				if(holder[i] == '+' || holder[i] == '-' || holder[i] =='*' || holder[i] == '/')
					output << holder[i] << "\n";
				if(holder[i] == ')')
					output << ")\n";
				if(isdigit(holder[i]) != 0)
				{
					output << holder[i];
					if(holder[i+1] == '.')
					{
						output << ".";
						i++;
					}

					if((holder[i+1] == '+' || holder[i+1] == '-' || holder[i+1] == '*' || holder[i+1] == '/' || holder[i+1] == '(' || holder[i+1] == ')') || i+1 == holder.length())
						output << "\n";
				}
				
			}

		}
		if(handling.eof())
			break;
	}
	output.close();
	return 0;
}
I've tried looking into this problem and believe it has something to do with my string size but I'm unsure. Could anyone tell me what might be the fix here?


It definitely has something to do with your string size. The fix: Pay attention to the size of the string.

The first thing you do is read in the token "read". Without checking the size of the string you read in, you check holder[0] and holder[1] which, in this case, happen to be present in the string, but since you didn't check whether the input operation was successful or the size of the data extracted, you have no way of knowing that.

Next, you check holder[4] to see if it's a space. 4 is not a valid index for a string holding a string of size 4. Valid indices would be 0-3. There are similar problems strewn throughout your code.
Last edited on
One thing might help ...

It would be better to have an IsOperator function (that returns a bool) which has a switch inside it. This is much more scalable than a huge if statement. And you have those if's in several places.

What made me notice this was the code being 2 screens wide . There is a sort of a rule that code should not be more than 80 chars per line. This makes it easier to read - I hate scrolling sideways all the time, and it is easier to print if that is needed.

The other contributor to this is the indenting. I see a lot of code on this site with indenting at 8 chars - which is too much. I am guessing this is because OP's have their tabs set to being actual tabs which are 8 spaces, whereas tabs being 4 spaces is much better.


HTH
Last edited on
This line is already

if(holder[x] == 'r' && holder[x+1] == 'e')

is invalid because the size of the string is unknown and it can be less than [x++1] and even [x] (for example when an empty string was entered). You should check that the subscript is always less than the size of the string.
Last edited on
Topic archived. No new replies allowed.