Program that reads vowels and erases them won't run properly - c++

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!

Related

how do you define an exact case constant with a switch statement in c++

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;
}

Code keeps printing "1" when everything is correct

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.

Using Pointers to pass C-String arguments

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;
}

Testing Index of String Array in c++?

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
char str[80];
int i=0;
cout<<"Enter the String ";
gets(str);
for (int j=0;str[j]!='\0';j++)
if (str[i]=='A'||'E'||'I'||'O'||'U')
i++;
cout<<"Number of vowels is: "<<i;
}
Here i am check element in String for Vowel, can anyone please suggest alternate method for this? I need to count number of vowels in string.
This code is working perfect for me, just need to find alternate method where i don't have to type too much "||" and 'a' and 'A' differently.
if (str[i]=='A'||'E'||'I'||'O'||'U')
this is wrong
should be like this:
if(str[i]=='A' || str[i]=='E'||str[i]=='I'||str[i]=='O'||str[i]=='U')
and also take care of case sensitiveness
str[i]=='A'||'E'||'I'||'O'||'U'
always returns true, because 'E' is always true. You're looking for
strchr("AEIOU", str[j])
Note the j, you got the loop variable wrong.
(Also, in C++, you'll want to use iostreams and getline instead of cstdio and fgets.)
A more C++-ish solution:
std::string vowels("aAeEiIoOuU");
for (int j=0;str[j]!='\0';j++)
{
if ( vowels.find(str[j]) != std::string::npos )
i++;
}
inline bool is_vowel(char a)
{
a=std::tolower(a);
switch(a)
{
case 'a': case 'e':
case 'i': case 'o':
case 'u':
return true;
}
return false;
}
int main()
{
std::string line;
std::cout << "enter text" << std::endl;
std::getline(std::cin, line);
int vowel=std::count_if(line.begin(), line.end(), is_vowel);
std::cout << "Number of vowels: " << vowel << std::endl;
}
Or use a table:
#include <iostream>
#include <string>
int main()
{
char list_v[256] = { 0 };
list_v['a'] = list_v['e'] = list_v['i'] = list_v['o'] = list_v['u'] = 1;
list_v['A'] = list_v['E'] = list_v['I'] = list_v['O'] = list_v['U'] = 1;
std::string str = "a sentence here";
uint32_t cnt = 0;
for (uint32_t i = 0; i < str.length(); i++)
cnt += list_v[str[i]];
std::cout << "found " << cnt << std::endl;
return 0;
}
or use map for the same purpose, or a c++ array/vector, people don't like c arrays here. This only works for ASCII of course.
Way? or syntax?
i think its a syntax error.. it should be like
if(str[i]=='A' || str[i]=='E'||str[i]=='I'||str[i]=='O'||str[i]=='U')
If you are asking about a better way, i don't think there is any..
You are doing in O(n) complexity, which is good enough i guess.! Even if you use hashing, you'll have to hash all the n characters in a string..

How to prevent the user from entering more than one character in the below sample code?

I am facing problem in the below code. If the user enter more than one charater then my loop gets executed number of times equal to the length of the string entered by the user. My code is written in GNU c/c++ compiler.
Thanks in advance.
int continue_option()
{
char c;
loop:
fflush(stdin);
cin.ignore();
cout<<"\n\n\t\t\t\tPress (Y/y) - Continue / Press (N/n) - Exit :";
cin>>c;
if(c=='y'||c=='Y')
{
system("clear");
}
else if(c=='n'|| c=='N')
{
exit(0);
}
else
{
printf("\n\t\t\t\tInvalid Option.Try Again.....");
goto loop;
}
fflush(stdin);
}
First thing, don't use jumps. They are old style, and they make Dijkstra spin in his grave, on top of all the other bad consequences. I don't mean "vintage", I really mean old in the bad sense.
As of your question, I'd rather put the result in a std::string and only consider the first character in there:
std::string input;
std::cin >> input;
switch (input[0]) {
case 'y':
case 'Y':
//your code
break;
case 'n':
case 'N':
exit(0);
default:
std::cout << "Invalid text" << std::endl;
}
I would also refrain from using exit(), I'd rather rely on a function's return value to finally cause a return 0; in the main(), or some equivalent technique.
You can't stop the user from typing more than one character.
What you can do is ignore the rest of the line. You have already use cin.ignore() which ignores one character. You can use cin.ignore(large number) to ignore up to the large number or the end-of-line, whichever appears first.
Unlike flushing output files, fflush(stdin) doesn't really do anything.
Try using cin.get() or getch() to read just one character at a time. Also, I guess you'd be better off replacing the whole thing with a simple loop like:
char ch = '\0';
do
{
ch = getch();
}while((tolower(ch) != 'y') || (tolower(ch) != 'n'))
if(tolower(ch) == 'y')
{
//additional handling
}
else
{
exit(0);
}
Not exactly the same behavior, but should put you on track:
#include <iostream>
#include <iomanip>
bool is_valid_answer(char c)
{
switch(c)
{
case 'y':
case 'Y':
case 'n':
case 'N':
return true;
default:
return false;
}
}
bool continue_option()
{
std::cout << "Press (Y/y) to continue, (N/n) to exit: " << std::flush;
char c = '\0';
while (std::cin.get(c) && !is_valid_answer(c));
return ((c == 'y') || (c == 'Y'));
}
int main()
{
std::cout << "Continue option: " << continue_option() << std::endl;
}