How to compare a char in a string to a specific char?

222 views Asked by At

I was tasked with writing a program in c++11 (though my example and code were made in 14) that takes a user inputted string and tells you how many lowercase vowels there are in the string. However, when I try to compare the ith value in a string to a char, I get an error message telling me that operand types (char and const char) are incompatible. The code for that looked like this:

std::string inWord;
int lowerVowels = 0;

std::cin >> inWord;

void searchString(std::string inWord, int& lowerVowels) {
    for (int i = 0; i < inWord.length(); i++) {
        if (inWord.at(i) == "a") {
            std::cout << "lowercase vowel found!";
            lowerVowels++;
        }
    }
}

So I tried declaring other strings like so:

std::string la = "a", le = "e", li = "i", lo = "o", lu = "u";

and made this absolute nightmare of a for loop inside my searchString function like this:

if (inWord.at(i) == la.at(0) || inWord.at(i) == le.at(0) ||
    inWord.at(i) == li.at(0) || inWord.at(i) == lo.at(0) ||
    inWord.at(i) == lu.at(0)) {
     lowerVowels++;       
}

Which worked, however I'm sure I'm missing an easier way here, because this felt ridiculous. If anyone can explain why the first try didn't work (or because it's kind of easy to assume why that happened) what I should've done instead (unless my solution is considered optimal, which I doubt) I'd love to hear it!

2

There are 2 answers

0
user12002570 On

You can create a std::set and use its find member or contains(in C++20) as shown below:

char la = 'a', le = 'e', li = 'i', lo = 'o', lu = 'u';
std::set<char> container = {la, le, li, lo, lu};
//with c++20
const bool is_in = container.contains(inWord.at(i));
if(is_in)
{
}

Pre C++20

//pre c++20
const bool is_in2 = container.find(inWord.at(i)) != container.end();
if(is_in2)
{
}

Note also that double quotes around like in "a" represents a string literal. What you actually wanted was a character literal which is created using a single quote. This means that you're trying to compare a string literal("a") which decays to a const char* to a char(inWord.at(i)) and hence the error operand types (char and const char*) are incompatible

0
Vlad from Moscow On

In the expression of this if statement

if (inWord.at(i) == "a") {

the string literal "a" has type const char[2]. Used as an operand of the equality operator it is implicitly converted to pointer to its first character of the type const char *.

On the other hand, the expression inWord.at(i) yields an object of the type char.

So actually you are trying to compare a character with a pointer that does not make sense.

Instead of the string literal you need to use a character literal like

if (inWord.at(i) == 'a') {

Nevertheless to count lower case vowels you could use member function find_first_of of the class std::string. For example

const char *vowels = "aeiou";
size_t lowerVowels = 0;

for ( std::string::size_type pos = 0; 
      ( pos = inWord.find_first_of( vowels, pos ) ) != std::string::npos; 
      ++pos )
{
   ++lowerVowels;
}

Here is a demonstration program.

#include <iostream>
#include <string>

int main()
{
    const char *vowels = "aeiou";

    std::string inWord( "Programming" );

    size_t lowerVowels = 0;

    for (std::string::size_type pos = 0;
        ( pos = inWord.find_first_of( vowels, pos ) ) != std::string::npos;
        ++pos)
    {
        ++lowerVowels;
    }

    std::cout << lowerVowels << '\n';
}

The program output is

3

The corresponding function can look the following way as shown below.

#include <iostream>
#include <string>

std::string::size_type searchString( const std::string &inWord, const std::string &vowels = "aeiou" )
{
    std::string::size_type lowerVowels = 0;

    for (std::string::size_type pos = 0;
        ( pos = inWord.find_first_of( vowels, pos ) ) != std::string::npos;
        ++pos)
    {
        ++lowerVowels;
    }

    return lowerVowels;
}

int main()
{
    std::string inWord( "Programming" );

    std::cout << searchString( inWord ) << '\n';
}