Loop until a specific char is entered (C++) - c++

I have a small problem here. This portion of code does not break the loop when the condition has been met. It is supposed to skip the loop if the user enters 'N', and to break if the user enters 'N' after each new loop prompt. Otherwise, it is the indefinitely loop with each input of 'Y'.
#include <iostream>
using namespace std;
void text();
char text()
{
char choice;
cout << "Enter Y/N: " << endl;
cin >> choice;
return choice;
}
int main()
{
text();
while(text() == 'Y' || text() == 'y')
{
text();
if(text() == 'N' || text() == 'n') {break;}
}
system("pause");
return 0;
}

The problem with the code is that you run text() function in every check, asking for input, the solution would be to store the result from text() into another variable like below:
#include <iostream>
using namespace std;
void text();
char text()
{
char choice;
cout << "Enter Y/N: " << endl;
cin >> choice;
return choice;
}
int main()
{
char choice;
choice = text();
while(choice == 'Y' || choice == 'y')
{
choice = text();
if(choice == 'N' || choice == 'n') {break;}
}
system("pause");
return 0;
}

The following will suffice:
#include <iostream>
int main(){
char choice = 'y';
while (std::cin && ::tolower(choice) == 'y'){
// do work
std::cout << "Enter Y/N: ";
std::cin >> choice;
}
}
If you insist on using a function then a simple void function with an argument passed by reference will do:
#include <iostream>
void choicefn(char& c){
std::cout << "Enter Y/N: " << std::endl;
std::cin >> c;
}
int main(){
char choice = 'y';
while (std::cin && ::tolower(choice) == 'y'){
// do work
choicefn(choice);
}
}
If you want to be really pedantic then modify the while statement to:
while (std::cin && ::tolower(choice) == 'y' && ::tolower(choice) != 'n')

Simply save the entered char in a char variable
char e = text();
while(e== 'Y' || e== 'y')
{
choice = text();
if(e== 'N' || e== 'n')
break;
}
Also erase the: void text();
You can't have two functions with the same name or one might say, can not overload functions distinguished by return type alone.

Related

finding out where to put [I] within my program

Below I am setting up a y/n question in the program, I know I need an identifier named i for the cin line to work in the if's. However, I'm not sure where to put my identifier.
#include <iostream>
#include <string>
using std::string, std::cin, std::cout, std::endl;
int main() {
const int MaxNum = 3;
int simcard;
string familyone[MaxNum] = {
"Name One",
"Name Two",
"Name Three"
};
int famnumone[MaxNum];
int choice;
string familytwo[MaxNum] = {
"Name One",
"Name Two",
"Name Three"
};
int famnumtwo[MaxNum];
string familythree[MaxNum] = {
"Name One",
"Name Two",
"Name Three"
};
int famnumthree[MaxNum];
string phonetype[MaxNum] = {
"Iphone",
"Android",
"Random Phone"
};
string familysim[MaxNum] = {
"Family one Sim",
"Family two Sim",
"Family Three Sim"
};
string simtype[MaxNum] = {
"Iphone SIM",
"Android SIM",
"Random Phone SIM"
};
//Here we have information for each family members name to later identify who each phone belongs too
cout << "SIM card matching tool\n";
cout << "Enter Family One Names ==>";
for (int i = 0; i < MaxNum; i++) {
getline(cin, familyone[i]);
}
do {
cout << "would you like to continue to the sim/y, or would you like to add another family/n" << endl;
cin >> choice;
choice = tolower(choice);
} while (choice != 'n' && choice != 'y');
if (choice == 'n') {
cin >> familytwo[i];
if (choice == 'y')
cin >> simtype[i];
}
//add y/n below or possibly add a more complex anwser "if you would like to continue with the SIM type SIM or if you would like to add another family type family
cout << "Would you like to continue to the SIM/y, or would you like to add another family/n";
}
I think you messesd up your do-while loop:
i=0;
do {
cout << "would you like to continue to the sim/y, or would you like to add another family/n" << endl;
cin >> choice;
choice = tolower(choice);
if (choice == 'n')
cin >> familytwo[i];
if (choice == 'y')
cin >> simtype[i];
i++;
} while (choice != 'n' && choice != 'y')
EDIT: you can increment i in every round.

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

Simple user input validation not working

I have a simple function that accepts either 1 or 2 and reprompts for input if neither of those two numbers are entered. Right now, if I enter any number, it stays stuck on asking for valid input. I know it's something easy, but I'm not seeing it now. What am I missing?
#include <iostream>
#include <string>
using namespace std;
int userChoice();
int main()
{
userChoice();
return 0;
}
int userChoice()
{
int input = 0;
cout << "Enter 1 or 2: ";
cin >> input;
while (input != 1 || input != 2 || cin.fail())
{
if (cin.fail())
{
cin.clear();
cin.ignore(1000, '\n');
}
cout << "Enter only 1 or 2: ";
cin >> input;
}
return input;
}
The conditional in while is not formed correctly. It will be always true.
You need to use something like:
while ( !cin || (input != 1 && input != 2) )
Suggestion for change of strategy
I think it will be better to use a recursive function:
int userChoice()
{
int input = 0;
cout << "Enter 1 or 2: ";
cin >> input;
// If we get a valid input, return.
if ( cin && (input == 1 || input == 2))
{
return input;
}
// If there is any error in reading, clear the stream.
if ( !cin )
{
cin.clear();
cin.ignore(1000, '\n');
}
// Call function again.
return userChoice();
}
Change the while condition to
while( (input != 1 && input !=2) || cin.fail())
use && not ||
#include <iostream>
#include <string>
using namespace std;
int userChoice();
int main()
{
userChoice();
return 0;
}
int userChoice()
{
int input = 0;
cout << "Enter 1 or 2: ";
cin >> input;
while ((input != 1) && (input != 2))
{
if (cin.fail())
{
cin.clear();
cin.ignore(1000, '\n');
}
cout << "Enter only 1 or 2: ";
cin >> input;
}
return input;
}

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

What is wrong with getchar (as program is exiting without a check at do while loop)?

In this in the main function the usage of getchar in do while loop is creating problem (as per what i m figuring out) and using getch resolves it..plz help why so..
#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
const int size = 10;
int main()
{
int stack[size];
int top = -1;
char ch;
char chh;
do {
cout << "what you want to do? 1:Push,2:Pop,3:Display \n";
cin >> ch;
if (ch == '1')
{
int a;
cout << "enter element to be entered";
a = getchar();
int r = push(stack, &top, a);
if (r == -1) cout << "array already full \n";
}
if (ch == '2')
{
pop(stack, &top);
}
if (ch == '3')
{
display(stack, &top);
}
cout << "enter y to continue";
chh = getchar();
} while (chh == 'y');
return 0;
}
Some else clauses will help. Put all those if's into one big if/else if/else loop:
if (ch == '1') { ... }
else if (ch == '2') { ... }
else if (ch == '3') { ... }
else { /*print out the bad char*/ }
You're likely getting a character that you're not expecting, like a carriage return.
Also, why are you mixing cin and getc?