use std::tolower() to find a keyword in a string

my programme:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
    int i, sep;
    string name = "We Are The Champion!";
    string keywords = "Champion";
    string word; 

    for(i = 0; sep != string::npos; i = sep + 1) {
        sep = name.find_first_of(" ,.!?", i);
        word = name.substr(i, sep - i);

        if(word == keywords) {
            cout << "Match found!" << endl; break;
        }
    }
    return 0;
}

but it does not work if keyword is changed to "champion" - small cap.


previously, i would do it in the following way to find keyword regardless of letter cases, if string name is one word only:
1
2
3
4
5
6
7
8
9
10
11
12
13
    int diff = 0;
    string name = "champion", keyword = "Champion";
    int lange = name.length();

    for(int i = 0; i < lange - 1; i++) {
        char alpha1 = name.at(i), alpha2 = keyword.at(i);
        alpha1 = tolower(alpha1); alpha2 = tolower(alpha2);
        if(alpha1 != alpha2)
          diff++;
    }

    if(diff == 0)
        cout << "Match found!" << endl;


but i have difficulties when name refers to a sentence. what should i do?


thanks!
One way is to make all lowercase.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main()
{
  string name = "We Are The Champion!";
  string keywords = "Champion";

  // make name lowercase
  for (char& ch : name)
    ch = tolower(ch); // #include <cctype>

  // make keywords lowercase
  for (char& ch : keywords)
    ch = tolower(ch);

  if (name.find(keywords) != string::npos)
    cout << "\nFound ";
  else
    cout << "\nNot found";

  system("pause");
  return 0;
}
thanks for the reply!

but i'm using code::blocks, and it said "error: range-based 'for' loops arenot allowed in c++98 mode" . and i'm not supposed to use c++11 features...

i did get the hints that we should include <cctype>. is there any other way i could convert the string to lowercase?

thanks!!

Just use a for-loop in the usual way.

This
1
2
  for (char& ch : keywords)
    ch = tolower(ch);
becomes
1
2
  for (size_t i=0; i<keywords.size(); ++i)
    keywords[i] = tolower(keywords[i]);

and so on.

size_t is an unsigned integer type large enough to store the size of any string.
thank you! it works.

but i will also do the conversion for the strings call from a class h. extension. in this case it has errors..

i may need to have a closer look at the codes before asking again..

thanks!
... c++98 mode

if I may, the first thing you need is an updated compiler ... you're missing out on so much of C++ post C++ 11
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <cstring>
#include <algorithm>

int main()
{
    std::string name = "We Are The Champion!";
    std::string keywords = "Champion";
    std::transform(begin(name), end(name), begin(name), ::tolower);
    std::transform(begin(keywords), end(keywords), begin(keywords), ::tolower);
    name.find(keywords) != std::string::npos ? std::cout << "Yes" << std::endl : std::cout << "No" << std::endl;
}
OP: std::regex_constants::icase could be an option if/when you move to a C++11 complier for case insensitive searches:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <regex>
#include <string>

int main()
{
    std::string name {"We Are The champion!"};
    std::regex re("\\bchampion", std::regex_constants::icase);
    //http://en.cppreference.com/w/cpp/regex/syntax_option_type
    bool match{false};
    std::sregex_iterator it(name.begin(), name.end(), re);
    std::sregex_iterator reg_end;
    for (; it != reg_end; ++it)
    //http://www.informit.com/articles/article.aspx?p=2064649&seqNum=5
    {
        std::cout << "Substring found: ";
        std::cout << it->str() << ", Position: ";
        std::cout << it->position() << std::endl;
        match = true;
        }
    if(!match)std::cout << "Not found \n";
}
@gunnerfunner
i'm not supposed to use c++11 features...

I know it sounds rather silly, but I think we have to accept these restrictions. This is probably some homework.
Last edited on
Quite right Thomas, but usually I have 3 reasons for making such posts:
(a) perhaps OP will upgrade at some point as in
 if/when you move to a C++11 compiler 

(b) for anyone else (for posterity?) who might be reading this and,
(c) quite selfishly, if I make a mistake someone far more experienced like you will correct me and I'll get a chance to learn myself!
Topic archived. No new replies allowed.