Counting number of vowels in a string

Pages: 12
Nov 29, 2014 at 5:07pm
I want to count all the vowels in a string (a, e, i , o, u) and display it as a text-based histogram for example:

[INPUT] The black cat sat up on the orange mat!

[OUTPUT]
A: *****
E: ***
I:
O: **
U: *

The asterisks are supposed to correspond to the number of vowels that are counted (using increments and the function setfill()).

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
31
32
33
34
35
36
37
38
39
40
41
42
43
 #include <iostream>
#include <string>
#include <iomanip>
using namespace std;


void calculateVowels(string text, int a_vowel, int e_vowel, int i_vowel, int o_vowel, int u_vowel)
{

	int a(0), e(0), i(0), o(0), u(0);
	for (int c = 1; c <= text.size(); c++)
	{
		if (text[c] == 'a')
			{a++;}
		else if (text[c] == 'e')
			{e++;}
		else if (text[c] == 'i')
			{i++;}
		else if (text[c] == 'o')
			{o++;}
		else if (text[c] == 'u')
			{u++;}
		
	}
	a_vowel = a, e_vowel = e, i_vowel = i, o_vowel = o, u_vowel = u;
}

int main()
{
	string text;
	cout << "Enter some text:" << endl;
	getline(cin, text);
	int a(0), e(0), i(0), o(0), u(0), non_space_characters;
	calculateVowels(text, a, e, i , o , u);
	cout << text << " " << a << " " << e << " " << i << " " << o << " " << u << endl;
		cout << "A:" << setfill('*') << setw(a) << endl;
		cout << "E:" << setfill('*') << setw(e) << endl;
		cout << "I:" << setfill('*') << setw(i) << endl;
		cout << "O:" << setfill('*') << setw(o) << endl;
		cout << "U:" << setfill('*') << setw(u) << endl;
	system("PAUSE");
		   return 0;
}


This is my output during compilation:

[OUTPUT]
The black cat sat up on the orange mat! 0 0 0 0 0
A:
E:
I:
O:
U:
Last edited on Nov 29, 2014 at 5:18pm
Nov 29, 2014 at 5:24pm
If you pass the variables by reference, the totals will update back in main. Right now you're only incrementing locally in the separate function.
Nov 29, 2014 at 5:25pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for (int c = 1; c <= text.size(); c++)
	{
		if (text[c] == 'a')
			{a++;}
		else if (text[c] == 'e')
			{e++;}
		else if (text[c] == 'i')
			{i++;}
		else if (text[c] == 'o')
			{o++;}
		else if (text[c] == 'u')
			{u++;}
		
	}


Arrays start at 0 not 1;


for (int c = 0; c < text.size(); c++)

The second thing:

int a_vowel, int e_vowel, int i_vowel, int o_vowel, int u_vowel

It can be confusing when passing arguments, that when done like this, you make a copy of the variable, if you want to pass it so any data manipulated is not local, then pass it by reference.

 
int& a_vowel, int& e_vowel, int& i_vowel, int& o_vowel, int& u_vowel


Let me know how it goes.
Nov 29, 2014 at 5:30pm
The fill is putting the asterisks at the front of each line, which isn't what you intend. Does the assignment require you use setfill()?
Nov 29, 2014 at 5:32pm
[OUTPUT]
aeiou 1 1 1 1 1
A:
E:
I:
O:
U:

It's not outputting the asterisks, in this case it should be one * for all the vowels

A: *
E: *
I: *
O: *
U: *
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
31
32
33
34
35
36
37
38
39
40
  #include <iostream>
#include <string>
#include <iomanip>
using namespace std;


void calculateVowels(string text, int& a, int& e, int& i, int& o, int& u)
{
	for (int c = 0; c < text.size(); c++)
	{
		if (text[c] == 'a')
			{a++;}
		else if (text[c] == 'e')
			{e++;}
		else if (text[c] == 'i')
			{i++;}
		else if (text[c] == 'o')
			{o++;}
		else if (text[c] == 'u')
			{u++;}
		
	}
}

int main()
{
	string text;
	cout << "Enter some text:" << endl;
	getline(cin, text);
	int a(0), e(0), i(0), o(0), u(0), non_space_characters;
	calculateVowels(text, a, e, i , o , u);
	cout << text << " " << a << " " << e << " " << i << " " << o << " " << u << endl;
		cout << "A:" << setfill('*') << setw(a) << endl;
		cout << "E:" << setfill('*') << setw(e) << endl;
		cout << "I:" << setfill('*') << setw(i) << endl;
		cout << "O:" << setfill('*') << setw(o) << endl;
		cout << "U:" << setfill('*') << setw(u) << endl;
	system("PAUSE");
		   return 0;
}
Last edited on Nov 29, 2014 at 5:33pm
Nov 29, 2014 at 5:35pm
My assignment does not state to use this function, but I have to some how get it output a histogram for each vowels counted.
Nov 29, 2014 at 5:40pm
You could use a loop that outputs a * according to the vowel count.
Nov 29, 2014 at 5:57pm
Could I just instead of incrementing each vowel, concatenate * by changing from int to string so I don't need setfill and setw
Nov 29, 2014 at 5:58pm
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
31
32
33
34
35
36
37
38
39
40
41
42
 #include <iostream>
#include <string>
#include <iomanip>
using namespace std;


void calculateVowels(string text, string& a, string& e, string& i, string& o, string& u)
{
	for (int c = 0; c < text.size(); c++)
	{
		if (text[c] == 'a')
			{a += '*';}
		else if (text[c] == 'e')
			{e += '*';}
		else if (text[c] == 'i')
			{i += '*';}
		else if (text[c] == 'o')
			{o += '*';}
		else if (text[c] == 'u')
			{u += '*';}
		
	}
}

int main()
{
	string text;
		char prev;
	cout << "Enter some text:" << endl;
	getline(cin, text);
		string a, e, i, o, u, non_space_characters;

	calculateVowels(text, a, e, i , o , u);

		cout << "A:" << a << endl;
		cout << "E:" << e << endl;
		cout << "I:" << i << endl;
		cout << "O:" << o << endl;
		cout << "U:" << u << endl;	
	system("PAUSE");
		   return 0;
}


This way works!
Nov 29, 2014 at 6:06pm
That works too.

You're only counting lower case? What if it were "A black cat..." instead of "The black cat..."
Nov 29, 2014 at 6:11pm
I know, also I need to program it to count the letters (excluding the spaces) that are NOT vowels.

[INPUT]
the black cat sat up on the orange mat!
[OUTPUT]
A: *****
E: ***
I:
O: **
U: *
Other (non-space) Characters: 20
Last edited on Nov 29, 2014 at 6:14pm
Nov 29, 2014 at 6:17pm
also I need to program it to count the letters (excluding the spaces) that are NOT vowels.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (int c = 0; c < text.size(); c++)
	{
		if (text[c] == 'a')
			{a += '*';}
		else if (text[c] == 'e')
			{e += '*';}
		else if (text[c] == 'i')
			{i += '*';}
		else if (text[c] == 'o')
			{o += '*';}
		else if (text[c] == 'u')
			{u += '*';}
		else if(text[c] == ' ')
                {
                        continue;
                }
                else nonvowel += '*'
	}
Nov 29, 2014 at 6:32pm
I want to display it as a number:

Other (non-space) Characters: 20
Nov 29, 2014 at 6:33pm
Or could I just do nonvowel.size() before outputting?
Nov 29, 2014 at 6:35pm
Or could I just do nonvowel.size() before outputting?


Try it. :)
Nov 29, 2014 at 6:39pm
It works! Thanks for your assistance!

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 #include <iostream>
#include <string>
#include <iomanip>
using namespace std;


void calculateVowels(string& text, 
					 string& a, string& e, string& i, string& o, string& u,
					 string& nonvowel)
{


	for (int c = 0; c < text.size(); c++)
	{
		if (text[c] == 'a')
			{a += '*';}
		else if (text[c] == 'e')
			{e += '*';}
		else if (text[c] == 'i')
			{i += '*';}
		else if (text[c] == 'o')
			{o += '*';}
		else if (text[c] == 'u')
			{u += '*';}
		else if (text[c] == ' ')
		{continue;}
		else 
		{nonvowel += '*';}
	}
}

int main()
{
	string text, a, e, i, o, u, nonvowel;
	cout << "Enter some text:" << endl;
	getline(cin, text);
	
	calculateVowels(text, a, e, i , o , u, nonvowel);
		cout << "A:" << a << endl;
		cout << "E:" << e << endl;
		cout << "I:" << i << endl;
		cout << "O:" << o << endl;
		cout << "U:" << u << endl;	
		cout << "Other (non-space) Characters: " << nonvowel.size() << endl;

	system("PAUSE");
    return 0;
}



Nov 29, 2014 at 6:41pm
One last question. What does 'continue;' do exactly or I'm I stating the obvious?
Last edited on Nov 29, 2014 at 6:41pm
Nov 29, 2014 at 6:49pm
Excellent work!

Now why don't you try and refactor your code a little? Make it tidier maybe? An extra function?

The keyword continue does exactly that, while in a loop such as that it skips to the end of the iteration, ready for the incrementation and the loop starts again, if that makes sense? Just think of it as a quicker iteration.

However the way it is used in that loop, taking it out would have no effect, the if will be called with an empty body, no code to process, skip to the next iteration.


I am glad to help. If you have any other queries, please let me know.
Nov 29, 2014 at 6:55pm
How and where do use tolower() function, when converting all characters in a string to lowercase?
Nov 29, 2014 at 7:02pm
Could I just simply use || in the condition state of my sub-routine?

For example:

if (text[c] == 'a' || text[c] == 'A')
{a += '*';}
Pages: 12