# Thread: Basic String Iteration Help, Best Solution?

1. ## Basic String Iteration Help, Best Solution?

I've written a sort of... parser, for lack of a better term. What this simple function does is take a string, look for ANY AND ALL control codes (denoted by starting with "[" and ending with "]"), and pass them on to a seperate function to be executed, right before deleting them from the string.

Now, I've noticed that whenever I use string::erase, it throws off any further iterations through the string. Observe:

Code:
```	string str = "Hey! It's a[1][01 45 00 01] test string.";

for(uint i = 0; i < str.length(); i++){
if(str.at(i) == '['){
const uint eb = str.find_first_of(']');
if(eb != max_int and eb > i){ //begin capture sequence
executeControlCode(str.substr(i + 1, (eb - i) - 1));
str.erase(i, (eb - i) + 1);
}
}
}```
Output:

"Hey! It's a[01 45 00 01] test string."

It captures the first control code properly, but not the second one... help with this?

EDIT: Wait a minute, if I place any sort of character between the 1st and 2nd control code, it captures both of them properly; why?!?

2. after cutting out the control string i will be incremented by the for loop. If you don't have any chars between control strings i will point to the char past the begin of the next control string.
simple fix
Code:
```	for(uint i = 0; i < str.length(); i++){
if(str.at(i) == '['){
const uint eb = str.find_first_of(']');
if(eb != max_int and eb > i){ //begin capture sequence
executeControlCode(str.substr(i + 1, (eb - i) - 1));
str.erase(i, (eb - i) + 1);
--i; // <<---
}
}
}```

Kurt

3. Yeah, that worked, thanks.

Oops, I thought npos was private.

4. Also you should not assume that std::string.find_first_of() returns a uint. You should be using a size_t, which is what this function returns. A size_t is not necessarily the same as a unsigned int, it could be any unsigned type.

Jim

5. Not sure what you mean; size_t typedefs to unsigned int?

6. typically, size_t is a typedef (possibly built-in) to unsigned long, and is guaranteed to be at least sizeof(void*) bytes wide, because it must, by definition, be capable of holding on to the size of things in bytes.