I have been stuck on this program all day. I finally feel like I'm getting really close. I have to find the number of vowels and characters in a string. Then output them at the end. However, when I compile my program crashes. I have checked syntax and looked in my book all day. If anyone can help I would really appreciate it! because I have 5 more similar functions to write that manipulate c-strings. Thanks!
#include <iostream>
#include <string>
using namespace std;
int specialCounter(char *, int &);
int main()
{
const int SIZE = 51; //Array size
char userString[SIZE]; // To hold the string
char letter;
int numCons;
// Get the user's input string
cout << "First, Please enter a string (up to 50 characters): " << endl;
cin.getline(userString, SIZE);
// Display output
cout << "The number of vowels found is " << specialCounter(userString, numCons) << "." << endl;
cout << "The number of consonants found is " << numCons << "." << endl;
}
int specialCounter(char *strPtr, int &cons)
{
int vowels = 0;
cons = 0;
while (*strPtr != '/0')
{
if (*strPtr == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U')
{
vowels++; // if vowel is found, increment vowel counter
// go to the next character in the string
}
else
{
cons++; // if consonant is found, increment consonant counter
// go to the next character in the string
}
strPtr++;
}
return vowels;
}
I'm going to assume you're limited to not using std::string or std::getline and that you have to assume the user inputs something less than 51 characters.
Your crash stems from:
while (*strPtr != '/0')
A null character is an escape code. '/0' is a multicharacter literal with an implementation-defined value. That means it's probably always true. Change it to:
while (*strPtr != '\0') //or while (strPtr)
Apart from that, you have a logic error with your vowel check. You have to check it against each vowel, like this:
if (*strPtr == 'a' || *strPtr == 'e') //etc.
You'll find it easier if you compare against the toupper or tolower version of each character to reduce the number of comparisons by a factor of 2.
while (*strPtr != '/0')
Should be:
while (*strPtr != 0)
or
while (*strPtr != '\0');
Didn't your compiler give you a warning? If so, don't ignore warnings. If not, get a better compiler.
See also the comments about the error in your other comparison.
Other answers should fix your issue, may I suggest you write separate functions instead of one almighty function?
bool IsSpecialChar(char c)
{
switch(c)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
return true;
}
return false;
}
int specialCounter(char *strPtr, int &cons)
{
int vowels = 0;
cons = 0;
while (*strPtr != '\0')
{
IsSpecialChar(*strPtr) ? vowels++ : cons++;
strPtr++;
}
return vowels;
}
Related
I'm learning C++ and I don't fully understand how case works in switch statements. I have the following code:
bool accept3() {
int tries = 1;
while (tries<4) {
std::cout<<"Do you want to proceed (y or n)?\n";
char answer = 0;
std::cin>>answer;
switch(answer) {
case 'y':
return true;
case 'n':
return false;
default:
std::cout<<"Sorry, but I don't understand that.\n";
tries ++;
}
}
std::cout << "I'll take that as a no.\n";
return false;
}
int main()
{
//accept();
//accept2();
accept3();
}
It works as expected when you input, 'y', 'n', or any other single character that does not meet the two defined cases.
When you input any string of characters that begins with n, it still takes that as the 'n' case. Why does it do this? How can I make this more exact, so that it ONLY accepts 'n' and not 'no', 'no way' or any other string beginning with 'n'.
Thank you!
This is tricky because if you input text with spaces into the terminal, like "d d d y", then you'll see the loop trigger 4 times in a row because "cin >> answer" breaks the line into separate inputs (this is called tokenization).
Here's code demonstrating how to properly parse an entire line of input as one menu command:
#include <iostream>
#include <string>
bool accept3() {
int tries = 1;
while (tries < 4) {
std::cout << "Do you want to proceed (y or n)?\n";
std::string answerStr;
std::getline(std::cin, answerStr);
char answer = '\0';
if (answerStr.size() == 1) {
answer = answerStr[0];
}
switch (answer) {
case 'y':
return true;
case 'n':
return false;
default:
std::cout << "Sorry, but I don't understand that.\n";
tries++;
}
}
std::cout << "I'll take that as a no.\n";
return false;
}
int main()
{
//accept();
//accept2();
accept3();
}
When you input any string of characters that begins with n, it still takes that as the 'n' case. Why does it do this?
Because you are asking cin to read a single char, so that is what it does. operator>>(char&) ignores leading whitespace, if any, and then reads 1 char. Any subsequent characters, if any, are left in the input buffer for later reads.
How can I make this more exact, so that it ONLY accepts 'n' and not 'no', 'no way' or any other string beginning with 'n'.
Use cin.getline() or std::getline() instead, and then compare the entire line, eg:
bool accept3() {
int tries = 1;
std::string answer;
do {
std::cout << "Do you want to proceed (y or n)?\n";
std::getline(std::cin >> std::ws, answer);
if (answer == "y")
return true;
if (answer == "n")
return false;
std::cout << "Sorry, but I don't understand that.\n";
++tries;
}
while (tries < 4);
std::cout << "I'll take that as a no.\n";
return false;
}
Instructions:
using a value returning function
Write a program that prompts the user to input a sequence of characters and outputs the number of vowels.
This is the problem given by the instructor..
#include <iostream>
using namespace std;
bool isVowel(char ch);
int main() {
char ch;
cout << "Enter a character: ";
cin >> ch;
cout << ch << " is a vowel: " << isVowel(ch) << endl;
return 0;
}
bool isVowel(char ch){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
return true;
} else
return false;
}
char is a single character, not a sentence. For a sentence use a string.
string s;
cout << "Enter a sentence: ";
cin >> s;
Then use a loop to loop through each character of the sentence
for (char ch : s)
{
...
}
Then use isVowel to test a single character, and increment the count if found. The clue is in the name isVowel, not countVowels, so isVowel should test a single vowel and return true or false, not count the number of vowels.
int vowels = 0;
for (char ch : s)
{
if (isVowel(ch))
vowels++;
}
finally write isVowel to test a single character.
bool isVowel(char ch)
{
return ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u';
}
There are several problems here.
Firstly, you don't initialize vowels. You presumably mean int vowels = 0; or int vowels {0};.
Secondly, you are reading a single character with cin >> ch;. I suspect you mean to loop over an input string.
Thirdly, your signature for isVowel is bool isVowel(int vowels, char ch);, which returns a bool. But you have written your function as thought it is manipulating an integer total of vowels. This inconsistency doesn't make sense.
Fourthly, you assign the result of isVowel to a character in ch = isVowel(vowels,ch);. Then you call isVowel again with this updated ch in cout << isVowel(vowels, ch) << .... I'm not sure what you're attempting to do here, but this also doesn't make any sense.
You need to revisit all of this code. You probably want isVowel to actually return a boolean. You probably want to iterate over an entire input string, and adjust the value of vowels appropriately (after initializing it).
Your program is running an undefined behavior; you are using vowels without being initialized.
You can make function that takes the counter of vowels as a reference to an integer for example.
void isVowel(int& counter, char ch) {
std::string vowels{ "AaEeIiOoUu" };
for (auto c : vowels)
if(ch == c)
counter++;
}
int main(){
char ch;
int counter{};
while (std::cin >> ch)
isVowel(counter, ch);
std::cout << counter << endl << " vowels in this sentence." << endl;
}
#include <iostream>
using namespace std;
bool isVowel(int vowels, char ch);
So isVowel returns a bool. That would make sense if its purpose was to tell us whether a single character was a vowel or not. For some reason, we pass an integer called vowels to it. That doesn't seem to make any sense. What would it do with an integer value?
int main() {
char ch;
So ch is a single character. Okay.
int vowels;
And vowels is an integer with no particular value.
cout << "Enter a sentence: ";
cin >> ch;
Uh oh. We ask the user to enter a sentence but then we read in a single character. Remember, ch was a char.
ch = isVowel(vowels,ch);
Uh oh. We didn't assign vowels any particular value, so we've passed no particular value to isVowel. Also, we took the boolean value returned and assigned to a variable of type char. Why would we do that?
cout << isVowel(vowels, ch) << " vowels in this sentence." << endl;
Then for some reason we call isVowel again. That doesn't make much sense. Also, isVowel returned a bool (a yes or no). Why are we outputting that as if it was the number of vowels?
return 0;
}
// build a string counter and make it callable
bool isVowel(int vowels, char ch){
Okay, so isVowel returns a boolean and takes as input an integer and a character.
for (int i = 0; i < ch; i++){
if (ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ||
ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u'){
vowels++;
}
We are looping from zero to the value of the single character? That doesn't make sense.
}
return vowels;
}
Lots of problems here. Because there are so many fundamental problems with this code, it seems you've attempted a problem that's way beyond your C++ knowledge and you should attempt something much simpler first, such as accepting a sentence as input and repeating it back to the user without using any additional functions.
I'm trying to make a simple mad libs program in c++, and i want to check and see if a word that a user entered starts with a vowel, and if it does, change the "a" before the word, to an "an". I've been able to get the first character stored, but it will not compare to the other characters in the If statement. Am i doing this completely wrong?
#include <string>
#include <iostream>
using namespace std;
int main() {
string adj_3;
string anN;
char firstChar;
// GETTING USER'S WORD
cout << "ADJECTIVE: " << endl;
getline(cin, adj_3);
// GETTING FIRST CHARACTER
firstChar = adj_3[0];
// SEEING IF IT'S A VOWEL (not working)
if(firstChar == ('a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'E' || 'I' || 'O' || 'U')) {
anN = "n";
}
else {
cout << "not working" << endl;
}
cout << "I am having a" << anN << " " << adj_3 << " time at camp." << endl;
}
The || operator needs to be applied to two arguments, like so:
if (firstChar == 'a' || firstChar == 'e' || firstChar == 'i' || ...)
firstChar == 'a' evaluates to a boolean. firstChar == 'a' || firstChar == 'e' takes the two booleans that results from those two operations, and returns another boolean, which is then fed into the next || operation as the first argument. In this way you can "chain" the || operations until one of them is true, or until they're all false.
See here for examples and explanation.
hnefatl's answer is one way.
You can also use switch case without break statements to check vowel. Something like:
switch(firstChar)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U': cout<<"Vowel";
}
On top of that switch-case have many advantages over if-else ladder as stated here https://stackoverflow.com/a/1028463/6594779.
Logical operator || combines two boolean expressions, e.g. a==0 || b==1, and returns true if either of the two operands is true. If you pass a single character like 'a' as operand, this will be interpreted as true, since the value of 'a' is 97 and 97 != 0 => true. Hence, your expression ('a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'E' || 'I' || 'O' || 'U') will always be true, and firstchar == (....) is the same as firstchar == true, which will probably give false.
You could write...
if (firstChar == 'a' || firstChar == 'e' || firstChar == 'i' || ...)
or...
if (strchr(firstChar, "aeiouAEIOU") != NULL)) ...
You can use an array too wherein you store all the vowels and then compare it. Something like shown below:
char vowels[10]={'a','e','i','o','u','A','E','I','O','U'};
int flag=0;
for(int i=0;i<10;i++)
{
if(vowels[i]==firstChar)
{
flag=1;
anN="n";
}
}
if(flag==1)
cout << "I am having a" << anN << " " << adj_3 << " time at camp." << endl;
else
cout << "not working" << endl;
I have a C++ program that finds and erases any vowels in a giving string. The only problem is, it doesnt work and I can't find the reason why. I have to use 2 functions that removes all the vowels and another that determines if a character is a vowel and all of this should operate in a loop.
This is my code:
#include <iostream>
#include <string>
using namespace std;
bool isA_Vowel(string s);
string remov(string s);
int main()
{
string s;
string ans = "y";
while((ans == "Y") || (ans == "y"))
{
cout << "Please enter a word or a series of letters: ";
cin >> s;
cout << "Old: " << s << endl;
cout << "New: " << remov(s) << endl;
cout << "Would you like to go again? <y/n> ";
cin >> ans;
}
}
bool isA_Vowel (string s)
{
if (s == "a" || s == "e"|| s == "i" || s == "o" || s == "u" || s == "A"
|| s == "E" || s == "I" || s == "O" || s == "U")
{
return (true);
}
else
{
return (false);
}
}
string remov(string s)
{
for (unsigned int i = 0; i < s.length(); ++i)
{
if (isA_Vowel(s))
{
s.erase(i,1);
}
}
return(s);
}
I had it working before, but now it won't run properly and erase all the vowels.
Any suggestions or tips would be awesome!
Thank you in advance!
Alright well I'm impantient and in a good mood, so here.
#include <iostream>
#include <string>
bool isVowel(char ch);
void removeVowels(std::string& str);
int main()
{
std::string Text = "";
std::cout << "Please enter a string, what ever you like: ";
std::getline(std::cin, Text);
removeVowels(Text);
std::cout << Text << std::endl;
return 0;
}
bool isVowel(char ch)
{
switch (ch)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
return true;
default:
return false;
}
}
void removeVowels(std::string& str)
{
int len = str.length();
int index = 0;
while (index < len)
{
if (isVowel(str[index]))
{
str = str.substr(0, index) + str.substr(index + 1, str.length());
len = str.length();
}
else index++;
}
}
The issue you were having was
I had it working before, but now it won't run properly and erase all the vowels. Any suggestions or tips would be awesome! Thank you in advance!
In your for loop don't use an unsigned int, just use an int!
Generally speaking you shouldn't really just return true or false "straight" as you've done here, there are a variety of reasons why, and I'm sure your professor will cover them. But for all intents and purposes declare a boolean variable (bool vowel = true) is an example of one and you can use that in your return.
Because you're using an if statement on it's own with no looping structure (and even with one you'd still have issues) it's only executing once which means at best it would only find one vowel. You're also returning true but you're not providing logic to handle it.
For instance what do you want to occur when it returns true, and what do you want it to do when it returns false?
You're using cin which does not and will not take multiples words (white spaces) use getline(cin, input); (input being your input variable)
I actually misread your code and I've changed my comment here to clarify. You say in your function to remove the vowel s.erase(i, 1); essentially what you're doing is starting at position 0 in your string iterating forward by 1 position and deleting the starting and ending point (starting point being 0 ending point being 1).
Remember the first position is 0 not 1.
If you've got questions about the code I provided you please let me know and I'll explain it to you!
The code runs and all but it doesn't print out the vowels, but instead prints a "1".
#include <iostream>
#include <string>
using namespace std;
int countVowels(string sentence,int numVowels)
{
for(int i =0; i<sentence.length(); i++)
{
if((sentence[i]==('a'))||(sentence[i]==('e'))||(sentence[i]==('i'))||(sentence[i]==('o'))||(sentence[i]==('u'))||(sentence[i]==('A'))||(sentence[i]==('E'))||(sentence[i]==('I'))||(sentence[i]==('O'))||(sentence[i]==('U')))
numVowels=numVowels+1;
}
}
int main()
{
string sentence;
int numVowels = 0;
do{
cout << "Enter a sentence or q to quit: ";
cin >> ws;
getline(cin,sentence);
}
if(sentence == 'q'|| sentence == 'Q');
cout << "There are " << countVowels << " vowels in your sentence." << endl;
return 0;
}
The output should be like this:
Enter a sentence or a to quit: I like apples!
There are 4 vowels in your sentence, and 11 letters.
Enter a sentence or q to quit: q
Bye!
My problem:
Can someone explain to me why it keeps printing a "1", and my "if" statement where I am supposed to assign the hotkey "q" to exit the program isn't working. When I run the program I get an error at the if statement saying "no match for operators=="
I usually don't like just providing a full solution, but since your question shows you have made a good effort, here's how I would write it (well, not quite, I simplified a little to be more beginner friendly):
#include <algorithm>
#include <iostream>
#include <string>
bool isVowel(char c)
{
// A simple function that returns true if the character passed in matches
// any of the list of vowels, and returns false on any other input.
if ( 'a' == c ||
'e' == c ||
'i' == c ||
'o' == c ||
'u' == c ||
'A' == c ||
'E' == c ||
'I' == c ||
'O' == c ||
'U' == c) {
return true; // return true if it's a vowel
}
return false; // remember to return false if it isn't
}
std::size_t countVowels(std::string const& sentence)
{
// Use the standard count_if algorithm to loop over the string and count
// all characters that the predicate returns true for.
// Note that we return the resulting total.
return std::count_if(std::begin(sentence),
std::end (sentence),
isVowel);
}
int main() {
std::string sentence;
std::cout << "Please enter a sentence, or q to quit: ";
std::getline(std::cin, sentence);
if ( "q" == sentence ||
"Q" == sentence) {
// Quit if the user entered a string containing just a single letter q.
// Note we compare against a string literal, not a single character.
return 0;
}
// Call the counting function and print the result.
std::cout << "There are "
<< countVowels(sentence) // Call the function on the input.
<< " vowels in your sentence\n";
return 0;
}
Hopefully the comments make it all clear.
Now you might have been told that you can't use the standard algorithms (std::count_if), since part of the exercise seems to be to write that. Well I'll leave that to you. Your current version is close to correct, but remember to return the result. And you don't really need to pass in the numVowels count, just create that within the function, and remember to return it.