2

example: "select * from somewhere where x = 1"

I want to find the whitespace-delimited "where", but not the "where" within "somewhere". In the example "where" is delimited by spaces, but it could be carriage returns, tabs etc.

Note: I know regex would make it easy to do (the regex equivalent would be "\bwhere\b"), but I don't want to add a regex library to my project just to do this.

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
djeidot
  • 4,542
  • 4
  • 42
  • 45

5 Answers5

7

If you wanted to use the pure MFC method of string manipulation, then this should work:

CString strSql = _T("select * from somewhere where x = 1");

int nTokenPos = 0;
CString strToken = strSql.Tokenize(_T(" \r\n\t"), nTokenPos);

while (!strToken.IsEmpty())
{
    if (strToken.Trim().CompareNoCase(_T("where")) == 0)
        return TRUE; // found
    strToken = strSql.Tokenize(_T(" \r\n\t"), nTokenPos);
}

return FALSE; // not found
Alan
  • 13,510
  • 9
  • 44
  • 50
  • I like this answer. It uses pure MFC, which I prefer, and also enables to do case insensitive searches. sbi's and JIa3ep's answers are also pretty good, though. – djeidot Jul 24 '09 at 13:52
3

I don't know the first thing about MFC and CString, but in plain C++ I'd stuff that string into an std::istringstream and read from that into a string:

std::istringstream iss("select * from somewhere where x = 1");
std::string word;
do {
  iss >> word;
  if( !iss ) throw "blah blah!";
} while( word != "where" );

I suppose CString does have stream operators overloaded with the appropriate semantics, but, as I said, I don't know it.

sbi
  • 219,715
  • 46
  • 258
  • 445
  • The extraction requires an ostream, and will read from any ostreambuf. You'd need an ostreambuf over CString to do this. – MSalters Jul 24 '09 at 13:37
  • @MSalters: Ah, `istream` -- _that_ I understand. Anyway, I wouldn't know whether there's any stream buffers for `CString`. I never used MFC. – sbi Jul 24 '09 at 16:17
2

Pretty fast and doesn't need to construct heavy istringstream objects.

CString str = L"select * from somewhere where x = 1";
CString to_find = L"where";
int i =0;
while ( i < str.GetLength() ) {
    i = str.Find(to_find, i);
    if ( i == -1 ) break;
    if ( (i == 0 || !isalpha(str[i-1])) && (i == str.GetLength()-to_find.GetLength() || !isalpha(str[i+to_find.GetLength()])) ) break;
    i+=to_find.GetLength();
}
if ( i >= 0 && i < str.GetLength() ) // found
else // not found
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
0

If you are using Visual Studio 2008 with Feature Pack you already have std::tr1::regex in C++.

Cristian Adam
  • 4,749
  • 22
  • 19
-1

Well, regex is the correct answer. If you don't want to include regex, you will have to try and implement a bit of regex yourself and search for " where ".

Your only other option I guess would be to search for "where", then check the character before and after the match to see if they are whitespace characters.

Rik Heywood
  • 13,816
  • 9
  • 61
  • 81