Expression: Subscript out of range


// Other solutions haven't helped me.
I have been searching high and low and inbetween for the issue here. I've seen many posts where this same issue is solved but the solution eludes me. Anyway, I got a job in which neither myself nor my boss expected us to need my one semester a long time ago of c++ skills.

//Start here to skip the whining
So, I get the error telling me Expression: Subscript out of range when I run this. Supposedly that means my for loop is sending i to infinity. If there are further problems with the code, I don't know to ask them yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  int main() 
{
	string line, filename1, filename2,filename_end;
	ifstream myfile;

	filename1 = "Hemisphere.stl"; //Just treat this as a string with some text		
	for (unsigned i = 0; i < filename1.length(); ++i) //Create output file name (Going to write the code for getting a filename instead of hardcoding it later.)
	{
		if (filename1.find('.') == string::npos)	//When the '.' is found,
		{
			filename_end = "KRC.txt";				//Take this text
			filename2 = filename2 + filename_end;	//Tack it onto the end
			i = filename1.length();					//Change i in order to end the loop
		}
		else filename2[i] = filename1[i];			//If '.' isn't found, just copy the current character to the second string
	
	}
	cout << filename2;	//Display
	cin.get();			//Await any user input

	return 0;
}			
Above, not sure why you need a loop?
This line, if (filename1.find('.') == string::npos) the == should be !=

Before going into the code, can I ask, what is the required result?

Is it something like:
input: "Hemisphere.stl"
output: "HemisphereKRC.txt"

1
2
3
4
5
6
7
8
9
10
11
    string filename1 = "Hemisphere.stl";
    string filename2 = filename1;        
    string filename_end = "KRC.txt";
 
    size_t pos =   filename2.rfind('.');    // find last occurrence of '.'
    if (pos != string::npos)                // if found, take substring up to that point.
        filename2 = filename2.substr(0, pos);
        
    filename2 += filename_end;

    cout << filename2;  


or probably better than substr(), just erase from pos to end.
1
2
3
    size_t pos =   filename2.rfind('.');    // find last occurrence of '.'
    if (pos != string::npos)                // if found, erase from pos to end.
        filename2.erase(pos);


http://www.cplusplus.com/reference/string/string/rfind/
http://www.cplusplus.com/reference/string/string/substr/
http://www.cplusplus.com/reference/string/string/erase/

Last edited on
That's exactly right. Take filename and make a copy with KRC.txt appended instead of .stl. I'm going to need more string handling soon so getting this naming business worked out would be good.
This works by the way. I'm certainly going to read those links. Thanks a bunch.
I'm going to need more string handling soon ...

In that case you may also wish to take a look at std::regex: http://www.cplusplus.com/reference/regex/ECMAScript/
(I find this link more useful than the actual regex link but that can also be accessed via above)
Regex does involve an initial learning curve but, over time, might justify that effort. For e.g your program in regex would look something like this (with #include <regex>):
1
2
3
4
    std::string target = "Hemisphere.stl";
    std::regex reg1("([\\.](.*)$)");
    target = std::regex_replace(target, reg1, "KRC.txt");
    std::cout << target << '\n';
> std::regex reg1("([\\.](.*)$)");
Character classes wrote:
Notice that within a class definition, those characters that have a special meaning in the regular expression (such as *, ., $) don't have such a meaning and are interpreted as normal characters (so they do not need to be escaped).

Also, use raw strings to avoid backslash hell http://en.cppreference.com/w/cpp/language/string_literal
Again, thanks to all of you guys. This certainly goes beyond what was covered back during that semester in college!
Topic archived. No new replies allowed.