#include <iostream>
int main() {
int fav_num {0};
bool in_range {false};
while (in_range == false) {
std::cout << "Enter your favorite number between 1 and 100: ";
std::cin >> fav_num;
if (fav_num < 1 || fav_num > 100 || !std::cin ) {
std::cout << "===Ops!, invalid choice, please try again.===" << std::endl;
std::cin.clear();
std::cin.ignore();
}
else {
std::cout << "Amazing!! That's my favorite number too!" << std::endl;
std::cout << "No really!!, " << fav_num << " is my favorite number!" << std::endl;
in_range = true;
}
}
std::cout << "==================================================" << std::endl;
return 0;
}
Why am I getting my output many times?
Once for q, once for w, once for e.
Check the docs for std::basic_istream::ignore. Without parameter, it skips only one character, so your loop will go through each character once, before it accepts new input again.
You want std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); to ignore every character until the next line.
Related
I have a segment of code here that runs partially. I am able to input both the characters (c, a, r) and numbers initially, but after entering a character input, the code no long accepts integer inputs. Why does this happen?
I think it has something to do with my try catch exception.
code:
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;
int item;
string input;
float total = 0;
int flag = 0;
float maintotal = 0;
int main() {
cout.precision(2);
cout << std::fixed;
cout << "Vending Machine" << endl;
cout << "----Items------" << endl;
vendingMachine();
cout << "Enter c to checkout" << endl;
cout << "Enter a to add items" << endl;
cout << "Enter r to remove items" << endl;
while (true) {
cout << "Enter your selection: " << flush;
cin >> input;
try
{
item = stoi(input); //convert to int
}
catch (exception &e)
{
//std::cout << e.what();
flag = -1; //if not set flag
if (input == "c"){
checkout();
}
if (input == "a") {
add();
cout << "mainadd total: " << total << endl;
}
if (input == "r") {
remove();
}
}
if (flag != -1) //only execute with no errors
{
total = enterSelection();
cout << "total from main: " << total << endl;
}
}
return 0;
}
Once you've set flag to -1, it's never changed back to 0. The initialization you perform at the top of the file happens just once, before main is even called. So, after that, when you set it to -1 in the catch block, it never went to a part of the code that set it back to 0. As you saw, setting flag = 0 at the beginning of the while loop corrects that omission.
So i'm trying to write a code that has the user putting in a name of a character from a video game and then they receive information about said character, like a pokedex from pokemon. I am trying to make my code loop back and give the option of putting in another name, but I can't seem to figure out which loop to use or how to implement one.
Here is what I have so far. I want the code to ask if you want to research another villager. I did some research and thought maybe a dowhile loop would work but I dont know what I'm doing in that regard. Any help would be appreciated.
#include <iostream>
#include <string>
int main()
{ std::string villager, tammy, genji;
std::cout << "Please enter a villager name.\n";
std::cin >> villager;
if (villager == "genji")
{
std::cout << " \n";
std::cout << "Genji\n";
std::cout << " \n";
std::cout << "Rabbit\n";
std::cout << "Male\n";
std::cout << "Jock\n";
std::cout << " \n";
}
else if (villager == "tammy")
{
std::cout << " \n";
std::cout << "Tammy\n";
std::cout << " \n";
std::cout << "Bear\n";
std::cout << "Female\n";
std::cout << "Jock\n";
std::cout << " \n";
}
std::cout << "Would you like to research another villager? Type yes or no.\n";
std::cin >> answer;
sorry if my formatting is weird, I've never used this forum before.
A do...while loop will work perfectly well.
The format is do {instructions} while (condition);.
I would recommend having a nested loop to verify that the input is yes or no.
#include <iostream>
#include <string>
int main()
{
std::string villager, answer;
do
{
std::cout << "Please enter a villager name.\n";
std::cin >> villager;
if (villager == "genji")
{
std::cout << "\nGenji\n\n";
std::cout << "Rabbit\n";
std::cout << "Male\n";
std::cout << "Jock\n\n";
}
else if (villager == "tammy")
{
std::cout << "\nTammy\n\n";
std::cout << "Bear\n";
std::cout << "Female\n";
std::cout << "Jock\n\n";
}
do
{
std::cout << "Would you like to research another villager? Type yes or no.\n";
std::cin >> answer;
} while(answer.compare("yes") != 0 && answer.compare("no") != 0);
} while(answer.compare("yes") == 0);
return 0;
}
You can use a do-while loop here:
int main()
{
std::string villager, tammy, genji, answer;
do {
// research villagers
std::cout << "Would you like to research another villager? Type yes or no.\n";
std::cin >> answer;
} while (answer == "yes");
}
This will research a villager once, and then continue to do this as long as the user enters "yes" at the prompt.
you can use while loop in your code.
bool isTrue = true;
while(isTrue){
.........
.........
your code here inside
.........
.........
if(name="x")
isTrue = false;
}
reference from https://meansflow.com/64/how-to-use-a-loop-back-in-c-to-make-the-program-infinite
You can see an example there
A Do-While is the best solution:
#include <iostream>
#include <string>
int main()
{ std::string villager, tammy, genji,answer;
do{
std::cout << "Please enter a villager name.\n";
std::cin >> villager;
if (villager == "genji")
{
std::cout << " \n";
std::cout << "Genji\n";
std::cout << " \n";
std::cout << "Rabbit\n";
std::cout << "Male\n";
std::cout << "Jock\n";
std::cout << " \n";
}
else if (villager == "tammy")
{
std::cout << " \n";
std::cout << "Tammy\n";
std::cout << " \n";
std::cout << "Bear\n";
std::cout << "Female\n";
std::cout << "Jock\n";
std::cout << " \n";
}
std::cout << "Would you like to research another villager? Type yes or no.\n";
std::cin >> answer;
}while(answer == "yes");
The Do-While do execute the code at least one time, so you have the possibility to do an operation and the ask to the user what prefer.
I'm a very beginner in C++ and I'm actually following the Google tutorial.
Trying to go a little further with the second example, here is my problematic : checking if the input is a number and, if not, being able to restate it in the error message.
Here is a way I used to solve that but the code length tells me that there is a shorter way :
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
using namespace std;
bool IsInteger(string str) {
size_t non_num_position = str.find_first_not_of("0123456789-");
size_t sign_position = str.find_first_of("-", 1);
if (non_num_position == string::npos && sign_position == string::npos) {
return true;
}
return false;
}
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
cin >> input_string;
if (!IsInteger(input_string)) {
int input_string_length = input_string.size();
cout << "Sorry but « " << input_string << " » is not a number." << endl;
cin.clear();
cin.ignore(input_string_length, '\n');
continue;
}
input_number = atoi(input_string.c_str());
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
int main() {
Guess();
return 0;
}
Here is the shorter way I try to follow but cin seems to be "emptied" once assigned to input_number (because of the bitwise operator ?) :
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
if (!(cin >> input_number)) {
getline(cin, input_string);
cout << "Sorry but " << input_string << " is not a number." << endl;
cin.clear();
cin.ignore(100, '\n');
continue;
}
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
SOLUTION :
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
cin >> input_string;
try {
input_number = stoi(input_string);
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
}
catch (const exception&) {
cout << "Sorry but " << input_string << " is not a number." << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
int main() {
Guess();
return 0;
}
The problem with your first attempt is that IsInteger is unnecessarily complicated and long. Otherwise, you had the right idea. Your second attempt is much less correct.... once you read from cin, the data is gone. So, as in the first attempt, you need to store the data in a string.
Here's an example which is a little shorter and doesn't need IsInteger at all:
size_t p = 0;
int input_number = std::stoi(input_string, &p);
if (p < input_string.length())
{
cout << "Sorry but " << input_string << " is not a number." << endl;
conitnue;
}
stoi's second argument tells you where the conversion to integer stopped working. So if there was non-int data in the string (such as '123abc') then p will be somewhere before the end of the string. If p is at the end, then the whole string must have been a number.
I'm creating my own very simple program that allows the user to input a numeric value. At the moment the code works just fine, but I need a validation if else statement. This is what I have at the moment;
#include <iostream>
#include <string>
using namespace std;
int main()
{
unsigned __int64 input = 0;
char str[] = "qwertyuiopasdfghjklzxcvbnm[]{};'#:#~,./<>?|!£$%^&*()";
cout << "Insert a number" << endl;
cin >> input;
if (input % 2 == 0)
{
cout << "Even!" << endl;
}
else
{
if (input% 2 == 1)
{
cout << "Odd" << endl;
cout << "Lets make it even shall we? " << "Your new number is... " << input + 1 << endl;
}
else if (isdigit(str[0]))
{
cout << "That isn't a number!" << endl;
}
}
system("pause");
return 0;
}
The issue I am having is that if the user inputs anything that isn't a number, the value it returns is "Even".
I hope you guys and girls can help!
John
Don't use token extraction (>>) for primary parsing. Once the extraction fails, your primary input is left in an unspecified state, which is terrible. Instead, read the input line by line and then process each line.
Also, never ignore the result of an input operation. That's just a flat error.
So, putting all this together, here's how you could handle this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
for (std::string line; std::cout << "Input: " && std::getline(std::cin, line); )
{
std::cout << "We're parsing your line '" << line << "'\n";
int n;
std::istringstream iss(line);
if (iss >> n >> std::ws && iss.get() == EOF)
{
std::cout << "It was a number: " << n << "\n";
}
else if (line.empty())
{
std::cout << "You didn't say anything!\n";
}
else
{
std::cout << "We could not parse '" << line << "' as a number.\n";
}
}
std::cout << "Goodbye!\n";
}
Note that all input operations (namely >> and getline) appear in immediate boolean contexts!
My program so far, my question is do i have to include the if statements after each cout/cin code or is there a way to generalize it? :
#include <iostream>
using namespace std;
int main ()
{
double watts, hours_per_day, watt_hours, dollars_per_wh, result;
dollars_per_wh= .00008;
cout << " How many Watts for the Air conditioner? ";
cin >> watts;
cout << " How many hours/day do you run the Air Conditioner? ";
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
cout << "How many Watts for the Television? " ;
cin >> watts;
cout << "How many hours/day do you run the Television? " ;
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
cout << "How many Watts for the Washer? " ;
cin >> watts;
cout << "How many hours/day do you run the Washer? " ;
cin >> hours_per_day;
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return 1;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return 1;
}
return 0 ;
}
You can write a function that takes two parameters:
bool check(int watts, int hours_per_day)
{
if (watts< 0)
{
cout << "Error- negative watts detected " << endl;
return false;
}
if (hours_per_day< 0)
{
cout << "Error - negative hours/day detected " << endl;
return false;
}
}
Then in your main function you can replace the two if statements with one:
if(!check(watts, hours_per_day))
{
return 1;
}
If you want to collect all the inputs first and then evaluate them, then maybe use an array for watts and hours_per_day. Then you can run through the array and check each entry.
Yes, you can pull them out into a separate function:
void cinNonNegative(double &x)
{
cin >> x;
if (x< 0)
{
cout << "Error- negative value detected " << endl;
exit(1);
}
}
int main()
{
...
cout << " How many Watts for the Air conditioner? ";
cinNonNegative(watts);
cout << " How many hours/day do you run the Air Conditioner? ";
cinNonNegative(hours_per_day);
...
}
And if you want to be more specific about the error message (e.g. "negative watts" instead of "negative value") you can add another parameter to cinNonNegative for the name of the variable (e.g. "watts").
The following solution gives you a function that:
Returns a boolean that says if the function succeeded/failed
Allows you to name the value that should be received
Allows you to set minimal and maximal values
If needed, you can build other custom functions for getting integers, or other functions for getting any other kind of input. This way you can concentrate all the input tests into a single place.
#include <iostream>
using namespace std;
bool getint(int &result, const char *name, int minValue, int maxValue)
{
bool success = false;
int value = 0;
cout << "Please enter " << name << ": ";
if (!(cin >> value))
{
cout << "Error: bad input detected" << endl;
}
else if (value < minValue)
{
cout << "Error: " << name << " is less than " << minValue << endl;
}
else if (value > maxValue)
{
cout << "Error: " << name << " is more than " << maxValue << endl;
}
else
{
success = true;
result = value;
}
return success;
}
int main()
{
int watts;
getint(watts, "Watts for the AC", 0, 10000);
return 0;
}