any one can try to fix this ?

coz im new in using c++ and my project is to create a vowel counter that showing the count of each vowel

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <windows.h>
#include <string.h>


char string[1000],c,choice;
int count=0;

int check(char *s,char c) //Function check, checks if the vowel A ,E ,I ,O ,U is in the string
{
int i,count=0;
for(i=0;s[i];i++)
{
if(s[i]==c)
{
count++; //increment count by 1 if the vowel is present
}
}
return count;
}

void VowelCounter () //Function VowelCounter counts and prints the number of Vowels in the string
{
printxy(8,13,"Enter the string : "); //user enters the string
gotoxy (8,14);
gets(string); //input for the string
strlwr (string); //switch the string to lowercase

count=check(string,'a'); //calls function check to count the number of letter 'A' in the string
gotoxy (8,15);
printf("A - %d \n ",count); //prints the number of letter 'A' in the string

count=check(string,'e'); //calls function check to count the number of letter 'E' in the string
gotoxy (8,16);
printf("E - %d \n ",count); //prints the number of letter 'E' in the string

count=check(string,'i'); //calls function check to count the number of letter 'I' in the string
gotoxy (8,17);
printf("I - %d \n ",count); //prints the number of letter 'I' in the string

count=check(string,'o'); //calls function check to count the number of letter 'O' in the string
gotoxy (8,18);
printf("O - %d \n ",count); //prints the number of letter 'O' in the string

count=check(string,'u'); //calls function check to count the number of letter 'U' in the string
gotoxy (8,19);
printf("U - %d \n ",count); //prints the number of letter 'U' in the string

gotoxy (8,21);
printf("Do you want to continue? [Y/Any Char]:"); //Asks the user if he wants to continue the program
choice = toupper (getche()); //gets the response of the user if he wants to continue
system ("cls"); //clearscreen
}
int main()
{
do{
box(2,2,78,24,178); // creates box
line2(4,4,76,22); //creates box with 2 lines
line1(6,6,74,9); //creates box with 1 line
line1(6,11,74,20);
center (7,"WELCOME TO VOWEL COUNTER"); //prints the string in the center
VowelCounter(); //calls Function VowelCounter

}
while (choice == 'Y'); //continue the program if user types 'Y'



}
How much money are you willing to pay us to do the work for you? We will assist you with problems you are experiencing, we won't do it all for you.

You didn't tell us what is wrong, and what you expect the correct output to be.

Please learn to use code tags, they make reading and commenting on source code MUCH easier.

How to use code tags: http://www.cplusplus.com/articles/jEywvCM9/

There are other tags available.

How to use tags: http://www.cplusplus.com/articles/z13hAqkS/

HINT: you can edit your post and add code tags.

Some formatting & indentation would not hurt either


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

void vowelCount( string &str )
{
   const string vowels = "aeiou";
   int freq[256] = { 0 };
   for ( unsigned char c : str ) freq[c]++;
   for ( unsigned char c : vowels ) cout << c << ": " << freq[c] + freq[toupper( c )] << '\n';
}

//-------------------------------------------------

int main()
{
    string str;
    cout << "Enter a string: ";   getline( cin, str );
    vowelCount( str );
}


Enter a string: Cry God for Harry, England and Saint George P!
a: 4
e: 3
i: 1
o: 3
u: 0
Last edited on
welcome!
My first piece of advice is, if you can (if this is self teaching), throw away whatever you are using to learn from. It looks like 30+ year old c++.
Instead, use learncpp.com site for a modern take on the language, including the C++ headers (most of yours are from C).

also read some best practices... global variables are easy to use, but are best not used without a very good reason to do so.
the gotoxy stuff can be fun esp if you do some console (text) games, but mostly put that aside and focus on the language basics (its from a third party library, not standard c++).

other than that, look at lastchance's code for what you kind of want to be doing for this exercise. Its short and much easier to follow. Remember that every line you write is a potential bug, so excess logic and convoluted code is best avoided for to-the-point approaches.
if you want the ascii-art, or its fun for you, go ahead, but do that AFTER the key part is working well as an add-on feature.
Since you already know what the explicit vowels will be before-hand, you could use an array of the values and std::find() in a loop that increments your position of the string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <array>
#include <string_view>
#include <xutility>

static constexpr std::array<char, 5> vowels ={'a' ,'e' ,'i' ,'o' ,'u'};
static constexpr std::array<unsigned int, 5> vowelCount = {};

void VowelCounter(std::string_view parseStr){    
    auto size {parseStr.size()};
    for(size_t pos{0}; pos < size ; ++pos){
    // effectively convert to lower-case to match
    auto ch {parseStr[pos]};
    if(ch >='A' && ch <= 'Z') ch-=32;
    // linear search through the vowel array and increment it's offset in the vowelCount array
    // You could also use a simple ranged for loop here instead of std::find() if performance
    // was of any concern.
    auto positionIfFound {std::find(vowels.begin(), vowels.end(), ch)};
    if( positionIfFound != vowels.end()){
            size_t index { static_cast<size_t>(std::distance(vowels.begin(), positionIfFound))};
            ++vowelCount[index];
        }
    }
}


and then have a function that prints out the frequency of each either in a separate function or in the original function; being in the original function it would look like:

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
#include <array>
#include <string_view>
#include <iostream>
#include <xutility>

static constexpr std::array<char, 5> vowels ={'a' ,'e' ,'i' ,'o' ,'u'};
static constexpr std::array<unsigned int, 5> vowelCount = {};

void VowelCounter(std::string_view parseStr){    
    auto size {parseStr.size()};
    
    for(size_t pos{0}; pos < size ; ++pos){
    // effectively convert to lower-case to match
    auto ch {parseStr[pos]};
    if(ch >='A' && ch <= 'Z') ch-=32;
    // linear search through the vowel array and increment it's offset in the vowelCount array
    // You could also use a simple ranged for loop here instead of std::find() if performance
    // was of any concern.
    auto positionIfFound {std::find(vowels.begin(), vowels.end(), ch)};
    if( positionIfFound != vowels.end()){
            size_t index { static_cast<size_t>(std::distance(vowels.begin(), positionIfFound))};
            ++vowelCount[index];
        }
    }
  // Print all the occurrences through indexing both arrays 
  auto vSize {vowels.size()};
  for(size_t pos{0}; pos < vSize; ++pos){
     std::cout << vowels[pos] << ": " << vowelCount[pos] << "\n";
  }
}


And using it like the above example would just be like so:

1
2
3
4
5
6
7
int main()
{
    std::string str;
    std::cout << "Enter a string: \n";
    std::getline( std::cin, str );
    VowelCounter(str);
}


std::string_view is C++17 so you would need to have C++17 support for that one bit, but you can easily replace that to const char*, char[], std::string, or whatever you would like.

EDIT: Also, like jonnin stated - get an updated learning resource. Most of what you have up there isn't C++ but rather C. It IS compatible with C++ since the standard requires C backwards compatibility, but you'll find that just because C++ is backwards compatible, the way you program in C++ is largely different than how you would normally program in C.
Last edited on
1) xutility shouldn't be directly used for #include - it is not a c++ standard include. Some compilers (eg VS) have one, but it can't be assumed to exist and if it exists to have the same interface between compilers.

2) vowelCount can't be constexpr as it's elements are changed.

3) a global variable shouldn't have it's contents changed. This should either be a function ref param or a return type.

4) To convert to lower-case, you add 32, not subtract
Last edited on
Based upon this method (although I prefer lastchance's version above), then:

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
#include <array>
#include <string_view>
#include <string>
#include <iostream>
#include <cctype>

static constexpr std::array vowels { 'a' ,'e' ,'i' ,'o' ,'u' };

auto VowelCounter(std::string_view parseStr) {
	std::array<size_t, vowels.size()> vowelCount {};

	for (unsigned char ch : parseStr)
		if (const auto positionIfFound { std::find(vowels.begin(), vowels.end(), static_cast<unsigned char>(std::tolower(ch))) }; positionIfFound != vowels.end())
			++vowelCount[positionIfFound - vowels.begin()];

	return vowelCount;
}

int main() {
	std::string str;

	std::cout << "Enter a string: ";
	std::getline(std::cin, str);

	const auto vls { VowelCounter(str) };

	for (size_t e {}; e < vls.size(); ++e)
		std::cout << vowels[e] << "  " << vls[e] << '\n';
}



Enter a string: Cry God for Harry, England and Saint George P!
a  4
e  3
i  1
o  3
u  0


An alternative to using std:array is to use std::map:

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
#include <string_view>
#include <string>
#include <iostream>
#include <map>
#include <cctype>

auto VowelCounter(std::string_view parseStr) {
	std::map<char, size_t> vowels { {'a', 0} ,{'e', 0}, {'i', 0},{'o', 0} ,{'u', 0} };

	for (unsigned char ch : parseStr)
		if (const auto it { vowels.find(static_cast<unsigned char>(std::tolower(ch))) }; it != vowels.end())
			++it->second;

	return vowels;
}

int main() {
	std::string str;

	std::cout << "Enter a string: ";
	std::getline(std::cin, str);

	for (const auto [v, c] : VowelCounter(str))
		std::cout << v << "  " << c << '\n';
}

Last edited on
It looks like the OP was c, not C++. AAhhh..

As c based upon the OP, then possibly:

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
#include <stdio.h>
#include <ctype.h>

int check(const char* s, char c) {
	int count = 0;

	for (; *s; ++s)
		count += tolower(*s) == c;

	return count;
}

void VowelCounter() {
	static const char* const vowels = "aeiou";
	char string[1000] {};

	printf("Enter the string: ");
	gets_s(string, 999);

	for (const char* v = vowels; *v; ++v)
		printf("%c - %d\n", *v, check(string, *v));
}

int main() {
	int choice {};

	do {
		VowelCounter();
		printf("Do you want to continue? [Y/Any Char]: ");
		choice = toupper(getchar());
		getchar();
	} while (choice == 'Y');
}

Yet the OP says they are new to C++. Not surprised they are using C, thinking it is C++.
xutility shouldn't be directly used for #include - it is not a c++ standard include
I mostly use VS which is why that popped up lol thank you as I hadn't known that wasn't a standard header.

vowelCount can't be constexpr as it's elements are changed.
Entirely correct - I'm not sure why I have constexpr for that array as it's being used to increment based on tracking

To convert to lower-case, you add 32, not subtract
This one was just a total oversight on my part - thank you for catching that.

Moral of the story - actually proofread my submission before hitting the submit button - thank you again for those points! The global arrays were just for the sake of ease in the example but I do agree with your third point on not having globals that tend to change.
“Cry ‘God for Harry, England, and Saint George P!'”

And, while we're on fractured Shakespeare
Yond Markle has a lean and hungry look;
She preens too much: such women are dangerous.
Awesome!

Sadly, I can still remember the original J.C. quote from O levels nearly 40 years ago.

But Meghan Markle reminds me more of Lady Macbeth:
cout damned spot!
Last edited on
LOL - also from Macosx by William Stroustrup:
Sudden, malicious, smacking of every cin


Double, float toil and trouble;
Fire burn, and cauldron bubblesort.
Topic archived. No new replies allowed.