9

I am learning to program C# and I am trying to count the vowels. I am getting the program to loop through the sentence, but instead of returning vowel count, it is just returning the length of the string. Any help would be greatly appreciated.

    static void Main()
    {
        int total = 0;

        Console.WriteLine("Enter a Sentence");
        string sentence = Console.ReadLine().ToLower();

        for (int i = 0; i < sentence.Length; i++)
        {
            if (sentence.Contains("a") || sentence.Contains("e") || sentence.Contains("i") || sentence.Contains("o") || sentence.Contains("u"))
            {
                total++;
            }
        }
        Console.WriteLine("Your total number of vowels is: {0}", total);

        Console.ReadLine();
    }
Phorden
  • 994
  • 4
  • 19
  • 43
  • You're using sentence.contains() each time, which will always be true if the sentence has a vowel! You need to test letter by letter. – vroomfondel Aug 07 '13 at 17:29
  • Your for loop loops through each character, but you're not actually using that character, you're checking if the entire sentence contains a vowel each time. – Michael Aug 07 '13 at 17:29
  • it's because you are checking the whole sentence each time and not the character. So you will always get the length as long as it contains at least 1 vowel – Papa Burgundy Aug 07 '13 at 17:29

20 Answers20

31

Right now, you're checking whether the sentence as a whole contains any vowels, once for each character. You need to instead check the individual characters.

   for (int i = 0; i < sentence.Length; i++)
    {
        if (sentence[i]  == 'a' || sentence[i] == 'e' || sentence[i] == 'i' || sentence[i] == 'o' || sentence[i] == 'u')
        {
            total++;
        }
    }

That being said, you can simplify this quite a bit:

static void Main()
{
    int total = 0;
    // Build a list of vowels up front:
    var vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u' };

    Console.WriteLine("Enter a Sentence");
    string sentence = Console.ReadLine().ToLower();

    for (int i = 0; i < sentence.Length; i++)
    {
        if (vowels.Contains(sentence[i]))
        {
            total++;
        }
    }
    Console.WriteLine("Your total number of vowels is: {0}", total);

    Console.ReadLine();
}

You can simplify it further if you want to use LINQ:

static void Main()
{
    // Build a list of vowels up front:
    var vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u' };

    Console.WriteLine("Enter a Sentence");
    string sentence = Console.ReadLine().ToLower();

    int total = sentence.Count(c => vowels.Contains(c));
    Console.WriteLine("Your total number of vowels is: {0}", total);
    Console.ReadLine();
}
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Maybe if you make this case insensitive could be a bit better. And also provide a link to `LINQ` for starters. – iCantSeeSharp Aug 07 '13 at 17:32
  • [i] is separating sentence into a char array to check per character instead of the whole sentence? – Phorden Aug 07 '13 at 17:33
  • @Phorden No - string has an indexer that returns a character without turning it into an array. – Reed Copsey Aug 07 '13 at 17:33
  • @Souvlaki It's already case insensitive - the original post used `ToLower`, and I kept that ;) – Reed Copsey Aug 07 '13 at 17:34
  • `int total = sentence.Count(c => vowels.Contains(c));` could be int total = sentence.ToLower().Count(c => vowels.Contains(c));` – Chase Florell Aug 07 '13 at 17:36
  • 1
    @ChaseFlorell No need - `string sentence = Console.ReadLine().ToLower();` "sentence" is already guaranteed lower case at that point. – Reed Copsey Aug 07 '13 at 17:36
  • Good call, I was testing it without reading line. I just used `var sentence = "TESTING";` and it came back `0`. – Chase Florell Aug 07 '13 at 17:38
  • A regex is just as simple as linq -- int total = Regex.Matches(sentence, @"[AEIOUaeiou]").Count; -- – Louis Ricci Aug 07 '13 at 17:45
  • @LastCoder You sure it's more efficient? It's easy enough, but regex compilation is probably going to be slower. (I do agree it's a good alternative, and did vote up your answer ;) ) – Reed Copsey Aug 07 '13 at 17:46
  • @LastCoder Just wired up a quick timing - the RegEx is about 5x slower than LINQ - probably doesn't matter (both are VERY fast in this case), but just an FYI. (If I precompile the regex, it speeds up subsequent matches, but still is slower...) – Reed Copsey Aug 07 '13 at 17:51
  • @ReedCopsey - Just for curiosity's sake, a foreach + Contains loop is actually the fastest, Regex is slower than Linq. http://ideone.com/OXYc3U In hindsight it makes sense since Regex.Matches is generating match objects. – Louis Ricci Aug 07 '13 at 18:01
  • @LastCoder Did you try one with my code? I was using HashSet for the Contains check - my timings were far lower for mine, but similar for regex... – Reed Copsey Aug 07 '13 at 18:05
  • @ReedCopsey - Yes the HashSet improves performance significantly. Changing the foreach loop over to one as well yields a similar gain. Keeping foreach + contains about 25% faster than linq Count http://ideone.com/AfZuZ6 which is curious since they are both performing the same thing, I guess linq just has a little more overhead. – Louis Ricci Aug 07 '13 at 18:20
  • @LastCoder LINQ typically has a slight overhead vs unrolling the loops, so that's pretty much expected. There's more allocations, so enough LINQ statements will often trigger a GC collection (or many), which is typically the difference. – Reed Copsey Aug 07 '13 at 18:24
  • `char[] vowels = { 'a', 'e', 'i', 'o', 'u' };` This works too. – puretppc Nov 30 '13 at 00:21
  • superb explanation Sir..!! – Nad Dec 13 '16 at 06:10
7

Since Reed has answered your question, I will offer you another way to implement this. You can eliminate your loop by using LINQ and lambda expressions:

string sentence = "The quick brown fox jumps over the lazy dog.";
int vowelCount = sentence.Count(c => "aeiou".Contains(Char.ToLower(c)));

If you don't understand this bit of code, I'd highly recommend looking up LINQ and Lambda Expressions in C#. There are many instances that you can make your code more concise by eliminating loops in this fashion.

In essence, this code is saying "count every character in the sentence that is contained within the string "aeiou". "

fatsmcgee
  • 314
  • 1
  • 4
3

That's because your if statement is always true, you need to compare the character at sentence[i], and see if it is a vowel, instead of seeing if the sentence contains a vowel.

CBredlow
  • 2,790
  • 2
  • 28
  • 47
2

Or with linq.

static void Main()
    {
        int total = 0;

        Console.WriteLine("Enter a Sentence");
        string sentence = Console.ReadLine().ToLower();
        char[] vowels = { 'a', 'e', 'i', 'o', 'u' };

        total = sentence.Count(x => vowels.Contains(x));

        Console.WriteLine("Your total number of vowels is: {0}", total);

        Console.ReadLine();
    }
Tyler
  • 578
  • 3
  • 10
2

You were checking to see if your whole sentence contained vowels for every iteration of your loop, which is why your total was simply the number of characters in your sentence string.

foreach(char ch in sentence.ToLower())
    if("aeiou".Contains(ch))
        total++;

Better yet use a regular expression. edit You'd only want to use a regex for something a little more complex than matching vowels.

using System.Text.RegularExpressions;
...
int total = Regex.Matches(sentence, @"[AEIOUaeiou]").Count;

EDIT Just for completeness the fastest/most efficient (if you were to do this on a ~million strings) solution. If performance wasn't a concern I'd use Linq for its brevity.

public static HashSet<char> SVowels = new HashSet<char>{'a', 'e', 'i', 'o', 'u'};
public static int VowelsFor(string s) {
    int total = 0;
    foreach(char c in s)
        if(SVowels.Contains(c))
            total++;
    return total;
}
Louis Ricci
  • 20,804
  • 5
  • 48
  • 62
1
int cnt = 0;
for (char c in sentence.ToLower())
    if ("aeiou".Contains(c))
       cnt++;
return cnt;
Curt
  • 5,518
  • 1
  • 21
  • 35
1

There are many ways to skin a cat :-) In programming a little lateral thinking can be useful...

total += sentence.Length - sentence.Replace("a", "").Length;
total += sentence.Length - sentence.Replace("e", "").Length;
total += sentence.Length - sentence.Replace("i", "").Length;
total += sentence.Length - sentence.Replace("o", "").Length;
total += sentence.Length - sentence.Replace("u", "").Length;

You could, for example, try removing a vowel from the sentence and looking if the sentence is smaller without the vowel, and by how much.

xanatos
  • 109,618
  • 12
  • 197
  • 280
0

Maybe too advanced for a starter, but this is the way you do that in C#:

var vowels = new[] {'a','e','i','o','u'};

Console.WriteLine("Enter a Sentence");
var sentence = Console.ReadLine().ToLower();

var vowelcount = sentence.Count(x => vowels.Contains(x));

Console.WriteLine("Your total number of vowels is: {0}", vowelcount);
Console.ReadLine();
Federico Berasategui
  • 43,562
  • 11
  • 100
  • 154
0

This is how I would handle this.

var sentence = "Hello my good friend";
            var sb = sentence.ToLower().ToCharArray();
            var count = 0;
            foreach (var character in sb)
            {
                if (character.Equals('a') || character.Equals('e') || character.Equals('i') || character.Equals('o') ||
                    character.Equals('u'))
                {
                    count++;
                }
            }
Antarr Byrd
  • 24,863
  • 33
  • 100
  • 188
0

You can also do this with switch statement

        var total = 0;
        var sentence = "Hello, I'm Chris";
        foreach (char c in sentence.ToLower())
        {
            switch (c)
            {
                case 'a':
                case 'e':
                case 'i':
                case 'o':
                case 'u':
                    total++;
                    break;
                default: continue;
            }

        }
        Console.WriteLine(total.ToString());
Chris
  • 681
  • 1
  • 6
  • 16
0

TMTOWTDI (Tim Toadie as they say: There's More Than One Way To Do It).

How about

static char[] vowels = "AEIOUaeiou".ToCharArray() ;
public int VowelsInString( string s  )
{

  int n = 0 ;
  for ( int i = 0 ; (i=s.IndexOfAny(vowels,i)) >= 0 ; )
  {
    ++n ;
  }

  return n;
}

Or (another regular expression approach)

static readonly Regex rxVowels = new Regex( @"[^AEIOU]+" , RegexOptions.IgnoreCase ) ;
public int VowelCount( string s )
{
  int n = rxVowels.Replace(s,"").Length ;
  return n ;
}

The most straightforward is probably the fastest, as well:

public int VowelCount( string s )
{
  int n = 0 ;
  for ( int i = 0 ; i < s.Length ; +i )
  {
    switch( s[i] )
    {
    case 'A' : case 'a' :
    case 'E' : case 'e' :
    case 'I' : case 'i' :
    case 'O' : case 'o' :
    case 'U' : case 'u' :
      ++n ;
      break ;
    }
  }
  return n ;
}
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
0
    static void Main(string[] args)
    {
        Char[] ch;
        Console.WriteLine("Create a sentence");
        String letters = Console.ReadLine().Replace(" ", "").ToUpper();
        ch = letters.ToCharArray();
        int vowelCounter = 0;
        int consonantCounter = 0;

       for(int x = 0; x < letters.Length; x++)
        {
            if(ch[x].ToString().Equals("A") || ch[x].ToString().Equals("E") || ch[x].ToString().Equals("I") || ch[x].ToString().Equals("O") || ch[x].ToString().Equals("U"))
            {
                vowelCounter++;
            }
            else
            {
                consonantCounter ++;
            }
        }
        System.Console.WriteLine("Vowels counted : " + vowelCounter);
        System.Console.WriteLine("Consonants counted : " + consonantCounter);
0

Application to count vowels and consonants letters in a sentence. This is another solution with less lines of code with understanding the idea of using loops and nested loops with char arrays.

An application interface with control names:

Application interface with controls names

namespace Program8_4
{
  public partial class Form1 : Form
  {
    // declare the counter variables in field
    int iNumberOfVowels = 0;
    int iNumberOfConsonants = 0;
    public Form1()
    {
        InitializeComponent();
    }

    private void btnFind_Click(object sender, EventArgs e)
    {
        // call the methods in this event
        GetVowels(txtStringInput.Text);
        GetConsonants(txtStringInput.Text);
        // show the result in a label
        lblOutput.Text = "The number of vowels : " + iNumberOfVowels.ToString()+ Environment.NewLine+
            "The number of consonants : " + iNumberOfConsonants.ToString();
        // assign zero the counters to not add the previous number to new number, and start counting from zero again
        iNumberOfVowels = 0;
        iNumberOfConsonants = 0;

    }

    private int GetConsonants(string strFindConsonants)
    {
        // Declare char array to contain consonants letters
        char[] chrConsonants = { 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'X',
            'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'x' };

        // loop to get each letter from sentence
        foreach (char Consonants in strFindConsonants)
        {
        // another nested loop to compare each letter with all letters contains in chrConsonants array
            for (int index= 0; index<chrConsonants.Length;index++)
            {
                // compare each letter with each element in charConsonants array
                if (Consonants == chrConsonants[index])

                {
                    // If it is true add one to the counter iNumberOfConsonants
                    iNumberOfConsonants++;
              }

            }
        }
        // return the value of iNumberOfConsonants
        return iNumberOfConsonants;
    }

    private int GetVowels(string strFindVowels)

    {
        // Declare char array to contain vowels letters
        char[] chrVowels = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O','U' };

        // loop to get each letter from sentence
        foreach (char Vowels in strFindVowels)
        {
            // another nested loop to compare each letter with all letters contains in chrVowels array
            for (int index = 0; index< chrVowels.Length; index++)
            {
                // compare each letter with each element in chrVowels array
                if (Vowels == chrVowels[index])

            {
                    // If it is true add one to the counter iNumberOfVowels
                    iNumberOfVowels = iNumberOfVowels+1;

            }
            }
        }
        // return the value of iNumberOfVowels
        return iNumberOfVowels;
    }
zx485
  • 28,498
  • 28
  • 50
  • 59
0

We can use regular expression to match vowels in a sentence.

Regex.Matches() function will return an array with all occurrence of vowel. Then we can use the count property to find the count of vowels.

Regular expression to match vowels in a string: [aeiouAEIOU]+

Below is the working code snippet:

 public static void Main()
   {
       string pattern = @"[aeiouAEIOU]+";
       Regex rgx = new Regex(pattern);
       string sentence = "Who writes these notes?";
       Console.WriteLine(rgx.Matches(sentence).Count);
   }
Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Rishu Ranjan
  • 494
  • 4
  • 7
0

// Using two loops.

        char[] vowels= new char[]{'a', 'e', 'i', 'o', 'u',
                                   'A', 'E', 'I', 'O', 'U'}; 
        string myWord= "This is a beautiful word.";
        
        int numVowels = 0;
        
        foreach(char c in  myWord.ToCharArray())
        {
            foreach(char c2 in vowels)
            {
                if(c == c2) numVowels++;    
            }  
        }
        
        Console.WriteLine($"{numVowels} vowels in: {myWord}");
0

We check each subsequent letter of the expression if it is equal to the vowels in the array

class Program
{

    private static void Main(string[] args)
    {
        string random = Console.ReadLine();
        string toLower = random.ToLower();
        char []isVowels = { 'a','e','i','o','u','y' };
        byte count = 0;
        for (int i = 0; i < toLower.Length; i++)
        {
            for (int j = 0; j < isVowels.Length; j++)
            {
                if (toLower[i]==isVowels[j])
                {
                    count++;
                }
            }
        }
        Console.WriteLine(count);
    }
    

}
0
`public static void Main()
{
    Console.WriteLine("Enter a Sentence");
    string sentence = Console.ReadLine().ToLower();

    string voval="aeiou";
    int cnt=0;
    foreach(char ch in sentence)
    {
        if(voval.Contains(ch.ToString()))
        {
            cnt++;
        }
    }
    Console.WriteLine(cnt); 
}`
0

Here was how I did it:

char[] englishWord = new Char[5] { 'a', 'e', 'i', 'o', 'u' };

string input = Console.ReadLine();

input.ToLower();

int count = 0;

for (int i = 0; i < input.Length; i++)
{
    for (int j = 0; j < englishWord.Length; j++)
    {
        if (input[i] == englishWord[j])
        {
            count++;
            break;
        }
    }
}

Console.WriteLine(count);
jeetjeet
  • 11
  • 2
  • Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Nov 19 '22 at 00:19
-1

this is a nice generic way to count vowels and from here you can do all sorts of things. count the vowels, return a sorted list, etc.

public static int VowelCount(String vowelName) {
            int counter = 0;
            char[] vowels = { 'a', 'e', 'i', 'o', 'u' };
            for (int index = 0; index < vowelName.Length; index++)
            {
                if (vowels.Contains(vowelName[index])) 
                {
                    counter++;
                }
            }
            return counter;
        }
castaway2000
  • 306
  • 5
  • 21
-1
void main()
{
    int x=0;
    char ch;
    printf("enter a statement:");
    while((ch=getche())='\r')
    {
        if(ch=='a'||ch=='e'||ch=='i'||ch=='o'||ch=='u')
        x++;
    }
    printf("total vowels=");
    getch();
}
Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
bilal
  • 1