How to check every character in string? - c++

The program will ask user to input strand which has to be composed of only ABCD and if the input contains letter other than ABCD it must show error, otherwise it should output "ok!"
string strand1;
again:
cout << "Enter String 1:\n";
cin >> strand1;
for (int i = 0; i <= strand1.length(); i++)
{
if (strand1.at(i) != 'A'&&strand1.at(i) != 'B'&&strand1.at(i) != 'C'&&strand1.at(i) != 'D')
{
cout << "Invalid Input";
system("cls");
goto again;
}
else
{
i++;
}
}
cout << "ok";
_getch();
return 0;

Move the necessary checks to a function -- isValidInput.
Use hand coded logic to check whether the input is valid or use the standard library function std::find_if to do the same.
Use the function in a while loop in the main function.
bool isNotABCD(char c)
{
return !((c == 'A') || (c == 'B') || (c == 'C') || (c == 'D'));
}
bool isValidInput(std::string const& str)
{
return (std::find_if(str.begin(), str.end(), isNotABCD) == str.end());
}
int main()
{
string strand1;
cout << "Enter String 1:\n";
while ( cin >> strand1 && !isValidInput(strand1) )
{
cout << "Invalid Input";
system("cls");
cout << "Enter String 1:\n";
}
cout << "ok";
}
Update
You can also use a simpler version of isValidInput(), Thanks to #Blastfurnace for the suggestion.
bool isABCD(char c)
{
return (c == 'A') || (c == 'B') || (c == 'C') || (c == 'D');
}
bool isValidInput(std::string const& str)
{
return (std::all_of(str.begin(), str.end(), isABCD));
}
Update 2
You can also use a still simpler version of isValidInput(), Thanks to #JorenHeit for the suggestion.
bool isValidInput(std::string const& str)
{
return (std::find_first_not_of("ABCD") == std::string::npos);
}

Your question is unclear, but after examining your code I believe the problem is that for your loop condition you are using i <= strand1.length when you should be using i < strand1.length.
The loop condition you are using will check an index out of bounds of the string. In addition, you should not be incrementing i in the else statement as that is already done in the for statement. In the future, please clearly state your question along with any error codes you are getting.

Related

I want to replace all the vowels with z in string

This code is replacing all the characters. Not just vowels. What am I doing wrong?
using namespace std;
bool isVowel(char);
int main() {
string fName = "";
string lName = "";
cout << "Enter first name: " << endl;
cin >> fName;
cout << "Enter last name: " << endl;
cin >> lName;
string name = fName + " " + lName;
cout << name << endl;
for(int i = 0; i < name.length(); i++) {
if(isVowel(name.at(i))) {
name[i] = 'z';
}
}
cout << name << endl;
}
bool isVowel(char c) {
if(c == 'a' || 'e' || 'i' || 'o' || 'u' || 'A' || 'O' || 'E' || 'I' || 'U') {
return true;
}
else {
return false;
}
}
I did some research online and I think my problem lies in that I am passing the character as a reference? I didn't understand how that could be...
The isVowel() function checks if the char is a vowel I think that's where the problem lies, since the program is replacing all the characters I'm assuming that function is not working.
you need to put your if statement as (c == 'a' || c == 'e' || c == 'i'..., the way it is written currently it casts all of the characters on their own as boolean expressions.

Fixing uninitialized local variable error

I am working on a project right now and when I try to run what I have below it gives me an error that says "uninitialized local variable 'userOption' used" on line 22, while (isValidOption(userOption) == true) {.
How do I fix that error? Thank you.
#include<iostream>
#include <string>
using namespace std;
char toupper(char ch) {
if (ch >= 'A'&&ch <= 'Z')
return(ch);
else
return(ch - 32);
}
bool isValidOption(char ch) {
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X')
return(true);
else
return(false);
}
char getMainOption() {
string UserInput;
char userOption;
while (isValidOption(userOption) == true) {
cout << "Choose One of the following options\n";
cout << "I--List Our Inventory\n";
cout << "O--Make an Order\n";
cout << "L--List all Orders made\n";
cout << "X--Exit\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
if (!isValidOption(userOption)) {
cout << "Invalid String\n";
cout << "Enter an option: ";
getline(cin, UserInput);
userOption = toupper(UserInput[0]);
}
if (userOption == 'I')
cout << "Listing Our Inventory\n";
else if (userOption == 'O')
cout << "Make an order\n";
else if (userOption == 'L')
cout << "Listing all orders\n";
}
return userOption;
}
int main() {
char choice;
choice = getMainOption();
system("pause");
return 0;
}
What the error is saying that you're trying to read from userOption before you've ever written to it. If a variable is uninitialized, its memory contents will be full of junk left behind by other functions and it can easily cause bugs. In your case, you'll want to read input from the user into userOption before you do any logic on it. This can be done with a do-while loop:
char userOption; // not yet initialized
do {
...
cin >> userOption; // userOption gets initialized here on first loop run
} while (isValidOption(userOption)); // no need for == true, that's a tautology :-)
// NOTE: perhaps you want to loop while the input is INvalid, as in
// while (!isValidOption(userOption)); ?
A couply code-review comments I would additionally give are:
std::toupper already exists in <cctype>. Docs are here
return is not a function call and it's better to write return ch; than return(ch);
if (ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X'){ return true; } else { return false; } is completely equivalent to the shorter return ch == 'I' || ch == 'O' || ch == 'L' || ch == 'X';
Also take a look at system(“pause”); - Why is it wrong?
Happy coding! Let me know if questions remain

Returning to the loop c++

I'm trying to do a simple game Guess Number and created a while condition to do that, but I want to insert a question to play again if the player type "Y" on the queue or close the window if the player type "N". My way is not working and I didn't find a solution for this problem.
int main()
{
int guess, number;
char again;
srand(time(0));
number = rand() % 1000 + 1;
while (guess != number)
{
std::cout << "Enter the number guess between 1 and 1000: ";
std::cin >> guess;
if (guess < number)
{
std::cout << "Is more than this" << std::endl;
}
else if (guess > number)
{
std::cout << "Is less than this" << std::endl;
}
else if (guess < 1)
{
std::cout << "The value to guess is between 1 and 1000" << std::endl;
}
else if (guess > 1000)
{
std::cout << "The value to guess is between 1 and 1000" << std::endl;
}
else
{
std::cout << "This is the number" << std::endl;
std::cout << "Do want play again? [Y/N ]" << std::endl;
std::cin >> again;
if (again == 'N' || again == 'n')
{
break;
}
else if (again == 'Y' || again == 'y')
{
continue;
}
}
}
When you correctly guess the number, your while condition becomes false and hence the loop exits (i.e. guess becomes equal to number, and hence the condition guess != number is false). Try changing to condition of the while loop.
char again = 'Y';
while (again == 'Y' || again == 'y') { ... }
Starting with some presumably yet unrecognised problem: You won't reach all of your if branches:
if (guess < number)
{ }
else if (guess > number)
{ }
// now if you really get to the following else, guess was neither
// smaller nor greater than number, i. e. is EQUAL!
else if (guess < 1)
{ /* won't ever be entered as number(!) is never < 1 (be aware: guess == number) */ }
else if (guess > 1000)
{ /* won't ever be entered as number is never > 1000 */ }
else
{ }
You can solve in two variants, by moving the unreachable checks either in front of the initial ones:
if (guess < 1)
{ }
else if (guess > 1000)
{ }
else if (guess < number)
{ }
else if (guess > number)
{ }
else
{ }
or into them:
if (guess < number)
{
if (guess < 1)
{ }
else
{ }
}
else if (guess > number)
{
if (guess > 1000)
{ }
else
{ }
}
else
{ }
Now to the actual problem, let's consider the else:
// be aware that guess == number now!
if (again == 'N' || again == 'n')
{
break; // fine so far...
}
else if (again == 'Y' || again == 'y')
{
continue;
// re-enters the loop - be aware that the condition is still checked!!!
}
// and if none of all was entered???
// as is, we'd just go on with the loop body - as this was the last statement,
// though, the loop will be re-entered by checking the condition; i. e. if
// getting here, we do effectively exactly the same as in the second if check
// above...
OK, so you (implicitly) defined a default of 'y'. You then could just simply remove the second if (else if == y) and nothing would change.
However, the loop condition is not true any more (guess == number still applies!). Easiest now: just make an endless loop of:
for(;;)
{
if(again == 'n')
break;
// obsolete, just drop it:
//if(again == 'y')
// continue;
}
I personally, though, would rather have the 'n' as default (so typing 'x', 'q', 'a' all result in exiting as well), so I'd rather have:
for(;;)
{
if(again != 'y' && again != 'Y')
break;
}

Getline() always takes input

I am capturing video from my webcam and if the user hits the Enter key I take a picture. Then I ask "Is the picture okay?" to user and wait for an input. If he says "No", I keep doing the same thing, until he says "Yes".
But if he says "No", and in the meantime I type something in the terminal, getline() function writes whatever I type into its buffer, and when I ask the question again it goes directly to "invalid input" state.
How do I prevent this?
I have read a lot of questions regarding this and I tried to use cin.ignore() and cin.clear() before/after after I call getline(), but they didn't help.
// Do capturing here
string choice;
int choiceIsOkay = 0;
while (choiceIsOkay == 0)
{
cout << "Is the picture okay? (Y/N): ";
getline(cin, choice);
if ((choice == "Y") || (choice == "y"))
{
choiceIsOkay = 2;
}
else if ((choice == "N") || (choice == "n"))
{
choiceIsOkay = 1;
}
else
{
cout << "\nInvalid input\n";
choiceIsOkay = 0;
}
}
if (choiceIsOkay == 2)
{
runAlgorithm = 1;
break;
}
else choiceIsOkay = 0;
If I understand your issue, if user enters Some Random Text In, your program always jump in "Invalid input" and never stops to wait for users input. Following code should resolve your issue.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int runAlgorithm;
// Do capturing here
int i = 0;
while (i++ < 3)
{
int choiceIsOkay = 0;
string choice;
while (choiceIsOkay == 0)
{
cout << "Is the picture okay? (Y/N): ";
getline(cin, choice);
if ((choice == "Y") || (choice == "y"))
{
choiceIsOkay = 2;
}
else if ((choice == "N") || (choice == "n"))
{
choiceIsOkay = 1;
}
else
{
cout << "nInvalid inputn";
choiceIsOkay = 0;
}
// Ignore to the end of line
cin.clear();
}
}
return 0;
}

Reprompt user after invalid input-c++

I modified the original code and the first two invalid input prompts work fine. when I implement the same logic into this prompt to start a new game, my program will not recognize an invalid input, with any key entered it will start a new game.
void newGame()
{
char newGameChoice = 'a';
cout << "\n--------------------------------------------------------------------------------" << endl;
cout << "Press N to play a new game\n";
cout << "Press X to exit\n\n";
cout << "--------------------------------------------------------------------------------" << endl;
cin >> newGameChoice;
newGameChoice = toupper(newGameChoice);
if (newGameChoice == 'N');
{
char userIn = 'a';
char c = 'a';
game(userIn, c);
}
while (newGameChoice != 'N' || 'X')
{
cout << "--------------------------------------------------------------------------------";
cout << "\n Invalid input. Please try again.\n" << endl;
cout << "--------------------------------------------------------------------------------" << endl;
newGame();
}
}
Your problem is this:
if (begin != 'B');
{
...
cin >> begin;
begin = toupper(begin);
start(); <------
You're calling start() again, which will read yet another value into begin.
Please spend more time analyzing your code before posting for help, it will help you to grow as a developer much more.
while (newGameChoice != 'N' || 'X')
is equivalent to
while (newGameChoice != 'N' || 'X' != 0)
Maybe what you mean is
while (newGameChoice != 'N' || newGameChoice != 'X')
Edit:
The code is wrong, it has to be rewritten, here is a suggestion:
void newGame()
{
char newGameChoice = 'a';
while (true) {
while (true) {
cin >> newGameChoice;
newGameChoice = toupper(newGameChoice);
if (newGameChoice != 'X' && newGameChoice != 'N') {
// Wrong input print error message
} else {
break;
}
}
if (newGameChoice == 'X') {
return;
}
game('a', 'a');
}
}
Part of your problem is that your start() method isn't designed in the most logical way. Currently when an invalid input is given, you attempt to read in another input and call start() again. When you called start() for the second time it starts back at the beginning of the start() method with no knowledge of the previous input.
What you should do instead is use a while() loop when an invalid entry is given and don't continue until a proper input is entered.
void start()
{
...
//Get initial user input
while begin != 'B'
{
Keep getting input if wrong
}
game(userIn, c);
}