1

For example I have the following string,

if (str[i] == '(' ||
    str[i] == ')' ||
    str[i] == '+' ||
    str[i] == '-' ||
    str[i] == '/' ||
    str[i] == '*')

My question is there a concise way to say if this value one of these set of values in c++?

sokkyoku
  • 2,161
  • 1
  • 20
  • 22

5 Answers5

6

You can search for single character str[i] in a string with your special characters: std::string("()+-/*").find(str[i]) != std::string::npos

Alexey Guseynov
  • 5,116
  • 1
  • 19
  • 29
  • 3
    It isn't really necessary to build an `std::string` object. String literal + `std::any_of` will do. – juanchopanza Sep 19 '16 at 09:08
  • Performance note: std::string will dynamically allocate buffer on a heap and copy string there. So if this code is in performance critical path of your program it is good to declare the string as `static const std::string specialChars("()+-/*")` and reuse it. In other cases I would prefer shorter code at cost of performance penalty. – Alexey Guseynov Sep 19 '16 at 09:15
3

Not glorious because it is C instead of C++, but the C standard library is always accessible from C++ code, and my first idea as an old dinosaur would be:

if (strchr("()+-/*", str[i]) != NULL)

Simple and compact

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
2

You may use the following:

const char s[] = "()+-/*";

if (std::any_of(std::begin(s), std::end(s), [&](char c){ return c == str[i]})) {
     // ...
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
0

It really depends on your application actually. For such a small check and depending the context, one acceptable option could be to use a macro

#include <iostream>
#define IS_DELIMITER(c) ((c == '(') || \
                         (c == ')') || \
                         (c == '+') || \
                         (c == '-') || \
                         (c == '/') || \
                         (c == '*')    )

int main(void)
{
    std::string s("TEST(a*b)");

    for(int i = 0; i < s.size(); i ++)
        std::cout << "s[" << i << "] = " << s[i] << " => " 
                  << (IS_DELIMITER(s[i]) ? "Y" : "N") << std::endl;
    return 0;
}

A more C++ish way of doing it would be to use an inline function

inline bool isDelimiter(const char & c)
{
  return ((c == '(') || (c == ')') || (c == '+') || 
          (c == '-') || (c == '/') || (c == '*')   );
}

This post might be interesting then : Inline functions vs Preprocessor macros

Community
  • 1
  • 1
Thomas W.
  • 460
  • 3
  • 9
-1

Maybe not "more concise", but I think this style is succinct and expressive at the point of the test.

Of course is_arithmetic_punctuation needn't be a lambda if you're going to use it more than once. It could be a function or a function object.

auto is_arithmetic_punctuation = [](char c)
{
  switch(c)
  {
      case '(':
      case ')':
      case '+':
      case '-':
      case '/':
      case '*':
          return true;
      default:
          return false;
  }
};

if (is_arithmetic_punctuation(str[i]))
{
  // ...
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142