Counting vowels and consonants in a string

Hi, for my homework assignment my teacher wants us to read a file word by word and count the vowels and consonants in that word, among other manipulations of the word.

Everything my my program works except the counting the vowels and consonants part. This is my function for counting the vowels

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int countvowels(string word, double wordlength) // Counting the vowels          
{
  int vowelcounter; // number of vowels in the word                             

  for(int i = 0; i<word.length(); i++)
    {
     if(word[i] == 'a' || word[i] == 'A' || word[i] == 'e' || word[i] == 'E' ||\
 word[i] == 'i' || word[i] == 'I' || word[i] == 'o' || word[i] == 'O' || word[i\
] == 'u' || word[i] == 'U')
       {
         vowelcounter++;
       }
    }
  return vowelcounter;
}


This is my function call in the main function

1
2
numberofvowels = countvowels(word,wordlength);
 vowelsum = vowelsum + numberofvowels;


I used the word "Here's" in my test, and my output was -176706046. I cant seem to find where its going wrong. Any help would be appreciated.
C++ does not initialize local variables.

1
2
3
4
5
int countvowels(string word, double wordlength) // Counting the vowels          
{
  int vowelcounter = 0; // number of vowels in the word (now init to zero!)

  ...

Have been introduced to switch statements? They can clean up those ugly and long if statements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
int main() 
{
	char tmp;
	int vowelCounter = 0;
	int consonantCounter = 0;
	string word = "temporaryword";
	
	for (int i = 0; i < word.size(); i++)
	{
		tmp = toupper(word[i]);
		switch(tmp)
		{		
			case 'A' :
			case 'E' :
			case 'I' :
			case 'O' :
			case 'U' :
				vowelCounter++;
				break;
			default:
				consonantCounter++;
		}
	}	
	cout << "Total vowels = " << vowelCounter << endl;
	cout << "Total consonants = " << consonantCounter << endl;		
		
	return 0;

}


A little function would prove more helpful:

1
2
3
4
5
6
7
#include <cctype>
#include <cstring>

bool isvowel( char c )
  {
  return strchr( "aeiou", tolower( c ) ) != NULL;
  }
^^^

Nice library use.

Here's a version of Duoas's function using C++ features:
1
2
3
4
5
6
#include <string>
#include <cctype>

bool isvowel(char c) {
    return std::string("aeiou").find(tolower(c)) != std::string::npos;
}


I had a more complicated template version that could also work on wchar_ts, but I decided that eh, there's no real point having it up.

-Albatross
Last edited on
^^^

Why do you not just include "using namespace std;"?


I see a lot of people on he explicitly declaring the std namespace but what I don't see is is those people declaring a conflicting namespace.

So, WTF?
It's a good habit if only because when you do get around to working with other libraries, there might be issues with conflicting names if you just include the namespaces. It may not be a problem in this one example.

Also, those namespace prefixes let you know for sure where everything is. If you're a good typist, then the (variable) benefits do outweigh the (slim) costs. :)

More information: http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-a-bad-practice-in-c

-Albatross
Last edited on
Ok, I see now.

I was ingrained in C++ for my degree but my goto prof always stated that including the std namespace was what I wanted.

Since then I have mostly been coding in C# and I include everything I need to using a "using" directive. For these dinky ass programs I still don't understand why people are so opposed to using the std namespace.

Wow, can't beleive I didnt notice that. I initialized several variables like that at other places in my code, oopsies haha. No I havent been introduced to switch statements, I am just starting filestreams. A lot of this stuff went over my head, but Ill get there someday.

Thanks for the help, and quick replies, its greatly appreciated. I know where Ill be coming back for help in the future. :)
Not a big deal, but when I use std::strings with a constant value I like to ensure that they'll be constructed just the once (I guess this might be wasted effort with modern compilers?).

1
2
3
4
5
6
7
#include <string>
#include <cctype>

bool isvowel(char c) {
    static const std::string vowels("aeiou");
    return vowels.find(tolower(c)) != vowels.npos;
}


And remember that a char not being a vowel does not make it a consonant. It could be a space or punctutation. So you might need to use the C library isalpha() call, too.
Last edited on
A actually purposefully avoided using std::string because of premature optimization syndrome...

In C++ I would write:

1
2
3
4
5
6
7
#include <cctype>
#include <string>

bool isvowel( char c )
  {
  return std::char_traits <char> ::find( "aeiou", 5, c ) != NULL;
  }

:but this is often a little more confusing to new coders...
Topic archived. No new replies allowed.