1

I am running into some unexpected string behavior when I append an Iterator to a string. Basically, I have a file that reads something along the lines of:

int x := 10;
print x;

I have a string already that contains the contents of this file, and I am iterating through it and simply removing whitespace right now.

void Lexer::parse()
{
    Pointer = Filestring.begin(); // both private members
    while(Pointer < Filestring.end())
    {
        if(is_whitespace(0)) // 0 indicates current Pointer position
        {
            advance(Pointer, 1);
            continue;
        }

        CurToken.append(&*Pointer); // CurToken is private member string
        advance(Pointer, 1);
    }

    cout << CurToken << endl;
}

By the end of the loop I would expect CurToken to be a string that contains nothing but the characters with all whitespace removed. Instead I get something like the following:

int x := 1 + 2;
print x;



nt x := 1 + 2;
print x;



t x := 1 + 2;
print x;

...

rint x;



int x;



nt x;



t x;



x;



;

I assume the issue is de-referencing the pointer, and if so, how can I append the current pointer position's character? If I do not de-refrence it, I end up with invalid conversion from ‘char’ to ‘const char*’

Note: is_whitespace() I have tested, and works as expected. So that can be ruled out as a possible problem.

7
  • Why are you not writing it instead of Pointer and do ++it instead of advance(Pointer,1)? Also, why not std::isspace(*it) instead of is_whitespace(0)? You're unnecessarily making it complicated. Commented Apr 19, 2012 at 14:55
  • Pointer is a string iterator * Commented Apr 19, 2012 at 14:55
  • What does *Pointer return? Why can't you use Pointer instead of &*Pointer? It looks like you might be appending the whole rest of the token each time you loop - not just one character. Commented Apr 19, 2012 at 14:59
  • It handles the whitespace correctly. Commented Apr 19, 2012 at 15:01
  • Why are you writing all this complicated non standard code for this? Tokenizing a file on whitespace is as easy as fstream f("file.txt"); string s; while(f >> s) cout << s << endl; Commented Apr 19, 2012 at 15:05

2 Answers 2

7
CurToken.append(&*Pointer);

Assuming Pointer is a pointer, that's equivalent to

CurToken.append(Pointer);

and will append the entire tail of the string onto CurToken (assuming it points to a C-style zero-terminated string; if there's no terminator then anything might happen). It looks like you just want to append the current character:

CurToken.append(*Pointer);

UPDATE: you say that Pointer is std::string::iterator. In that case, &*Pointer is still a pointer to the character; and append will still interpret it as a pointer to a C-style string. Since the characters in a string aren't necessarily terminated (although in practice they almost certainly will be, especially in a C++11 library), you've got undefined behaviour.

Sign up to request clarification or add additional context in comments.

4 Comments

I would have assumed Pointer is a home-brewed smart pointer.
its string::iterator Pointer;
@MarkB: Perhaps; quite a complicated one, since you can do arithmetic on it. Even so, &* would have the same effect as if it were a plain pointer.
@Headspin: OK, that will have the same effect as if it were a pointer, but with extra undefined behaviour. You still want *Pointer to get just the current character.
1

What are the types of CurToken and Pointer? CurToken looks like a std::string. Is Pointer a std::string*? append has quite a few overloads. One of them is:

string& append ( const string& str );

If you want to hit that one you should get rid of the '&' to give you just the dereferenced pointer:

CurToken.append(*Pointer);

That should work, but remember that it'll append the whole string not just the character. If it doesn't you probably need to figure out which overload of append() it's hitting. If you want the first character only, try:

CurToken.append(1, (*Pointer)[0]); 

1 Comment

Perfect. I think you best understood what I was trying to accomplish here, although I had to use CurToken.append(1, (Pointer)[0]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.