Reputation:
In my project I take a string from user and then I need to check if vowels a, e, I, O, U are present. If so, I have to find out which one comes first in the string and which one comes next after that. For example, if a user gave input something like this:
char expr[] = "this is for something real";
I comes first, then I again, then O and so on. I checked whether the characters are in the string or not using strchr(expr,'character here')
. To find which character comes first, I find the index of each character using
const char *ptr = strchr(expr, characters here);
if(ptr) {
int index = ptr - expr;
}
After that I check which index is bigger. But this is very long process. Is there a smarter way to do this?
Upvotes: 1
Views: 181
Reputation: 61910
Here's a method that gives you the characters found, as well as the indices (in order automatically). It also makes use of some C++ features, rather than C:
int main() {
std::string expr = "this is for something real";
std::string toCheck = "AaEeIiOoUu"; //checking for these letters
std::map<int, char> indices; //stores index-character pairs
for (char c : toCheck) { //go through each char in string (ranged-for, C++11)
if (expr.find (c) != std::string::npos)
indices [expr.find (c)] = c; //map sorts itself by key
}
for (const auto &element : indices) { //print results
std::cout << "'" << element.second << "'"
<< " found at index " << element.first << '\n';
}
}
I'm not sure if it offers anything else you need over David's answer, but it's one way to do it, and does allow for more information to be pulled. The current code, however, will only give you the first occurrence of each. I'm not sure whether you wanted all or the first, but it is adaptable. At that point, though, David's answer fits in quite nicely.
Upvotes: 0
Reputation: 208323
If you don't need the locations in the original string, but only the order, you can use std::remove_copy_if
with a functor that detects non-vowel characters (i.e. returns true for vowels):
std::string only_vowels;
std::remove_copy_if( std::begin(expr), std::end(expr),
std::back_inserter(only_vowels),
[]( char ch ) { char upper = toupper(ch);
return upper!='A'
&& upper!='E'
&& upper!='I'
&& upper!='O'
&& upper!='U'; } );
(Using C++11 features to obtain the iterators and a lambda instead of creating a functor, but the same can be written in C++03 with a bit of extra boiler plate code. Code is untested)
After the algorithm completes, only_vowels
will contain only the vowels present in the original string and in the exact order where they appeared. Case is not modified by the algorithm.
Alternatively you can iterate manually over the elements in the string, and test each character to see whether it is a vowel, then print it or do whatever needs to be done. If this is homework, this is probably what is expected from you.
Upvotes: 1
Reputation: 19032
This can be done pretty easily by simply iterating over the input expression and noting when the target letters are encountered. Here's a C++11
way that will fill a std::vector
with the vowels in the order they are seen in the input expression. If you just need to print them out, then just don't fill the results
vector (print them instead).
char expr[] = "this is for something real";
std::vector<char> results;
std::for_each(
expr,
expr + strlen(expr),
[&results] (const char c)
{
switch(c)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
results.push_back(c);
}
});
Upvotes: 1