Find the vowels in a string

VitzzViperzz

Well-known member
Joined
Jan 16, 2017
Messages
75
Location
United Kingdom
Programming Experience
1-3
Hello,

So I tried making an application that would take in a sentence as a string and then find how many vowels are in that sentence. But it failed.

I tried using the IndexOf function but it couldn't take more than 1 argument - which is rubbish as we have more than a vowel. I then tried passing the number of vowels found to console, but it was pointless.

Here is the code:

C#:
namespace VowelCounter
{
    class Program
    {
        static void Main(string[] args)
        {
            string userInput;
            Console.WriteLine("Enter a string: ");
            userInput = Console.ReadLine();
            string vowelsToFind = "a";
            int index = userInput.IndexOf('a');
            Console.WriteLine($"Found {vowelsToFind}, in {userInput}, at position {index}");
            Console.ReadKey();
        }
    }
}

Could anyone suggest a better way to do this? and a way that takes more arguments?

Thanks
 
Look into Regex for Regular Expressions and do a count. If you need further help or code I can take a look later when I'm at a computer.

Sent from my SM-G955U using Tapatalk
 
Thank you for your reply.

I want to keep it as simple as possible. I have not yet used regular expressions and don't quite know what they are.

But I will do some digging and see what I can come up with. Thank you for the input.
 
No problem. The only other way (Regex is simple for me however) is using loops and indexof but that's clunky and better handled by Regex.

Sent from my SM-G955U using Tapatalk
 
There's no need to use IndexOf to count vowels because, according to your requirement, you don't care about indexes. The String class implements the IEnumerable<char> interface so you can use a 'foreach' loop to enumerate the chars in a string, e.g.
var vowelCount = 0;

foreach (var ch in myString)
{
    if (IsVowel(ch))
    {
        vowelCount++;
    }
}

I'll leave it to you to write that IsVowel method.
 
There's no need to use IndexOf to count vowels because, according to your requirement, you don't care about indexes. The String class implements the IEnumerable<char> interface so you can use a 'foreach' loop to enumerate the chars in a string, e.g.
var vowelCount = 0;

foreach (var ch in myString)
{
if (IsVowel(ch))
{
vowelCount++;
}
}

I'll leave it to you to write that IsVowel method.

This is the code that I tried writing for the IsVisible method and then trying to output the result:

C#:
void IsVowel()
            {
                char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
                string[] foundVowels;
                var vowelCount = 0;
                userInput.Contains(vowels);
                if (userInput.Contains(vowels))
                {
                    vowelCount++;
                }
            }






           
            foreach (var ch in userInput)
            {
                if (IsVowel(ch))
                {
                   // write the number of vowels 
                }
            }

It's an ambitious attempt but my skills really aren't that sharp. I looked on the internet but everyone wants a single character. I want a set of them to be searched for. I have had no luck.

Any pointers?
 
There are a number of issues there. Firstly, your IsVowel method is named and used as though it will take a char as an argument and return a bool indicating whether the char passed in is a vowel or not but it is not declared with a char parameter, not declared to return a bool and the implementation is counting. That method should have a char parameter and return a bool. The implementation should start with a list of vowels and then return a bool that indicates whether that list contains the char that was passed. That's two lines of code. Your loop is correct as far as it goes, but it's in that loop that you should be incrementing a count, not in the IsVowel method.

This is what comes from trying to write code without knowing what it's actually supposed to. If you only have a vague idea of the final outcome then you never know whether what you're writing is doing what it is supposed to do. For instance, if you had started with a clear idea of what that IsVowel method was supposed to do then it would have been clear that it doesn't really get anywhere close to it. For instance, you should known that you needed to return a bool before writing any code so you can then look at that and see that it's not returning a bool and know that that's wrong. To be effective, you need to plan your code before writing it.
 
There are a number of issues there. Firstly, your IsVowel method is named and used as though it will take a char as an argument and return a bool indicating whether the char passed in is a vowel or not but it is not declared with a char parameter, not declared to return a bool and the implementation is counting. That method should have a char parameter and return a bool. The implementation should start with a list of vowels and then return a bool that indicates whether that list contains the char that was passed. That's two lines of code. Your loop is correct as far as it goes, but it's in that loop that you should be incrementing a count, not in the IsVowel method.

This is what comes from trying to write code without knowing what it's actually supposed to. If you only have a vague idea of the final outcome then you never know whether what you're writing is doing what it is supposed to do. For instance, if you had started with a clear idea of what that IsVowel method was supposed to do then it would have been clear that it doesn't really get anywhere close to it. For instance, you should known that you needed to return a bool before writing any code so you can then look at that and see that it's not returning a bool and know that that's wrong. To be effective, you need to plan your code before writing it.

Thank you very much for your input. You're certainly correct about me not being able to plan before I start writing code - but I think that could be more down to my lack of programming skills.

I did try another bit of code:

C#:
bool hasVowel;


            void IsVowel()
            {
                userInput.Contains("a") 


                if (userInput.Contains(vowels))
                {
                    vowelCount++;
                }


                return hasVowel;
            }

I am dedicated to learning but if I am not getting any closer, let's just forget this case and I will come back to it later down the line.

Thank you for your help
 
Here's what I mean about planning before writing code. This is my original code snippet:
var vowelCount = 0;

foreach (var ch in myString)
{
    if (IsVowel(ch))
    {
        vowelCount++;
    }
}
In that code, the IsVowel method is receiving a char as an argument, meaning that it MUST have a char parameter, and it is being used as the subject of an 'if' statement, meaning that it MUST return a bool:
bool IsVowel(char ch)
{
    bool result;

    // ...

    return result;
}
That code can be written simply by observing and analysing the usage of the method. Now think about what such a method needs to actually do. It's receiving a single char and it needs to determine whether that char is a vowel. There are multiple vowels so they could be written as a list, so you want to know whether the specified char is contained in such a list of vowels. So it makes sense to create a list of vowels and then check whether it contains the specified char:
bool IsVowel(char ch)
{
    bool result;
    var vowels = new [] {'a', 'e', 'i', 'o', 'u'};

    result = vowels.Contains(ch);

    return result;
}
Because we made a plan before writing that code, we can now look at the code and check whether it actually implements the plan and, if it doesn't, we know that the code is wrong and needs to be changed, assuming that we had a sound plan to begin with. That code can then be simplified to this:
bool IsVowel(char ch)
{
    var vowels = new [] {'a', 'e', 'i', 'o', 'u'};

    return vowels.Contains(ch);
}
That will only find lower-case vowels, but I'll leave the rest to you.
 
Last edited:
Here's what I mean about planning before writing code. This is my original code snippet:
var vowelCount = 0;

foreach (var ch in myString)
{
if (IsVowel(ch))
{
vowelCount++;
}
}
In that code, the IsVowel method is receiving a char as an argument, meaning that it MUST have a char parameter, and it is being used as the subject of an 'if' statement, meaning that it MUST return a bool:
char IsVowel(char ch)
{
bool result;

// ...

return result;
}
That code can be written simply by observing and analysing the usage of the method. Now think about what such a method needs to actually do. It's receiving a single char and it needs to determine whether that char is a vowel. There are multiple vowels so they could be written as a list, so you want to know whether the specified char is contained in such a list of vowels. So it makes sense to create a list of vowels and then check whether it contains the specified char:
char IsVowel(char ch)
{
bool result;
var vowels = new [] {'a', 'e', 'i', 'o', 'u'};

result = vowels.Contains(ch);

return result;
}
Because we made a plan before writing that code, we can now look at the code and check whether it actually implements the plan and, if it doesn't, we know that the code is wrong and needs to be changed, assuming that we had a sound plan to begin with. That code can then be simplified to this:
char IsVowel(char ch)
{
var vowels = new [] {'a', 'e', 'i', 'o', 'u'};

return vowels.Contains(ch);
}
That will only find lower-case vowels, but I'll leave the rest to you.

I am starting to get the hang of methods and return values. I had a look at your 'Beginner tutorial' and it explained it very well.

I can understand that with the last bit of code you are returning the vowels that were in ch. But I don't understand how that works? because I get an error that says I need to convert the value of a bool to a char.

I tried a few solutions, but it seems a little strange.

Then I tried to convert all of the user's input to a lowercase using the ToLower() function:

C#:
            string userInput;
            Console.WriteLine("Enter a string: ");
            userInput = Console.ReadLine(userInput.ToLower());

But it seems that I need to push it to a lowercase in the WriteLine procedure.

Am I getting closer to a working program or drifting away from it? I can sense the learning and because I have put the methods to test (with your help) and have learned some interesting things.

I just wanted to know your opinion as to what areas I should patch up before I move on further through the book.

Thanks.
 
Last edited:
Sorry, I've managed to confuse matters now. As I said in the post, the method must return a bool, but I accidentally declared the method to return a char. I've fixed the code in my previous post so have another look and it might make more sense. The method is not returning the vowels that were in 'ch' but rather returning a bool, i.e. 'true' or 'false', that indicates whether 'ch' was contained in the array of vowels, i.e. whether 'ch' is a vowel.
 
Sorry, I've managed to confuse matters now. As I said in the post, the method must return a bool, but I accidentally declared the method to return a char. I've fixed the code in my previous post so have another look and it might make more sense. The method is not returning the vowels that were in 'ch' but rather returning a bool, i.e. 'true' or 'false', that indicates whether 'ch' was contained in the array of vowels, i.e. whether 'ch' is a vowel.


Hello!

I managed to do it!

Check the code out:

C#:
namespace VowelCounter
{
    class Program
    {


        static bool IsVowel(char ch)
        {
            bool result;
            var vowels = new[] { 'a', 'e', 'i', 'o', 'u' };
            result = vowels.Contains(ch);


            return result;
        }


        static void Main(string[] args)
        {
            string userInput;
            Console.WriteLine("Enter a string: ");
            userInput = Console.ReadLine();
            var vowelCount = 0;


            foreach (var ch in userInput)
            {
                if (IsVowel(ch))
                {
                    vowelCount++;
                }
            }


            Console.WriteLine(vowelCount);


            Console.ReadKey();
        }
    }
}

After the bool and char replacement, all I had to do was make the IsVowel method a static and it worked. Otherwise, the (IsVowel(ch)) would state and error.

Thank you for the help jmcilhinney.
 
Back
Top Bottom