0

std::find is not evaluating as I expected.

I have a vector lexeme_ defined as

static const std::string delimiters_[] = {" ", ",", "(", ")", ";", "=", ".", "*", "-"};

static std::vector<std::string> lexeme_(std::begin(delimiters_), std::end(delimiters_));

I have an evaluation using std::find defined as

while ( std::find(lexeme_.begin(),lexeme_.end(),std::string(&commandLine_.at(position_))) == lexeme_.end())             
{
    // Concat each successive alphanumeric character to 'token'
    token += commandLine_.at(position_);
    // Update the index into 'commandLine'
    position_ += 1;
}

The evaluation is supposed to compare a char in lexeme_ to a char in commandLine similar to this Java expression

!lexeme.contains(Character.toString(commandLine.charAt(position)))  

The evaluation is supposed to compare chars and if it determines a char in delimiters is satisfied in the comparison, then the while loop will exit.

Testcase

#include<algorithm>
#include<iostream>    

static const std::string delimiters_[] = {" ", ",", "(", ")", ";", "=", ".", "*", "-"};

static std::vector<std::string> lexeme_(std::begin(delimiters_), std::end(delimiters_));

std::string commandLine = "check me";

while (std::find(lexeme_.begin(),lexeme_.end(),std::string(&commandLine_.at(position_))) == lexeme_.end())             
{
    std::cout "I should stop printing when encountering a space ' ' << std::endl;
}
Mushy
  • 2,535
  • 10
  • 33
  • 54
  • 1
    Can you construct a complete test-case to demonstrate this? – Oliver Charlesworth Apr 08 '13 at 21:30
  • @DrewDormann needs citation. As stated, that is ludicrous. It is certainly not "certainly" faster. – sehe Apr 08 '13 at 21:33
  • So what is the problem? What does this code do, and what did you expect it to do, and how does what it does do differ from what you expect it to do? In short, http://whathaveyoutried.com/ – jalf Apr 08 '13 at 21:34
  • It looks like you're trying to construct an (expression) parser. Would you like help with that? See e.g. [Expression Parser](http://stackoverflow.com/questions/8464969/boostspirit-expression-parser/8468822#8468822), [Veryfiying Algebraic Expressions](http://stackoverflow.com/questions/15123412/how-to-verify-algebraic-statements-using-boostspirit/15123959#15123959), [Calculator Sample](http://stackoverflow.com/questions/15486531/boostspiritqi-defining-a-calculator-for-nullaries/15488691#15488691) (note, I like [tag:boost-spirit] and [tag:coco-cpp]) – sehe Apr 08 '13 at 21:38
  • @DrewDormann You're gonna have to show some evidence for that claim. – Etienne de Martel Apr 08 '13 at 21:43

2 Answers2

3

The constructor for your temporary comparison string is incorrect. It isn't building a single-character string, it's building a string starting at that character and going to the end of the original string, if you're lucky - there might be some std::string implementation out there somewhere that doesn't automatically zero terminate the internal buffer.

So instead of this:

std::string(&commandLine_.at(position_))

Use:

std::string(1, commandLine_.at(position_))
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Thank you. Also, converting `delimiters_` to a `char` array and making `lexeme_` a `std::vector` works as well. – Mushy Apr 08 '13 at 21:57
2

This expression:

 std::string(&commandLine_.at(position_))

Creates an std::string object by passing a pointer to a char object. However, a pointer to a char object is a (null-terminated) C-string, not a pointer to a single character.

There is no constructor of std::string that accepts a single character. You could make your vector a vector of chars, and then search for commandLine_.at(position_) inside that vector.

However, judging from your test case, it seems to me all you want is the find_first_of() member function of std::string:

#include <algorithm>
#include <iostream>

int main()
{
    std::string commandLine = "Check me";
    std::string delimiters = " ,();=.*-";
    auto pos = commandLine.find_first_of(delimiters);
    std::cout << pos;
}

Here is a live example.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • BTW he goes in to the while loop if he didn't find; not when he found. (whatever he is looking for) –  Apr 08 '13 at 21:42
  • @stardust_: Right, that was the result of a copy-paste gone wrong. I edited anyway, thank you – Andy Prowl Apr 08 '13 at 21:49