Why do I have this infinite loop - c++

hey guys kind of new to the programming world and I know you should read in all input as a string but this is just a simple program and I'm having a brain fart I think but here is my question......why when I press q to quit am i getting an infinite loop and how would I condense the while loops because that looks gross
here is what I have so far
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int grade;
char quit = 'a';
cout << "Input your grade (0-100): ";
cout << endl;
cin >> grade;
while (grade < 0) {
cout << "If you have a negetive grade....drop out! otherwise enter another grade" << endl;
cin >> grade;
}
while (quit != 'q') {
while (grade < 0) {
cout << "If you have a negetive grade....drop out! otherwise enter another grade" << endl;
cin >> grade;
}
if (grade == 100) {
cout << "You got a perfect grade!" << endl;
cout << "Letter grade: A" << endl;
}
else if (grade >= 90 && grade <= 100) {
cout << "Letter grade: A" << endl << endl;
}
else if (grade >= 80 && grade <= 89) {
cout << "Letter grade: B" << endl << endl;
}
else if (grade >= 70 && grade <= 79) {
cout << "Letter grade: C" << endl << endl;
}
else if (grade >= 60 && grade <= 69) {
cout << "Letter grade: D" << endl << endl;
}
else if (grade < 60) {
cout << "Letter grade: F" << endl << endl;
}
else {
cout << "Invalid grade!" << endl;
}
cout << " would you like to enter another grade? or press q to quit" << endl;
cin >> grade;
}
system("pause");
return 0;`enter code here`
}

Because of grade var. You declared grade as int.
If you type correct int, it works well, but If you type another char ex:) q or f, function cin cannot recognize q or f as int type.
If char input, cin pass own process.
You have to change grade type into char to recognize char and int inputs both.
If you want to use only one input flow, this implementation code will help you.
int _tmain(int argc, _TCHAR* argv[])
{
char c_input[32] = {0};
cin>>c_input;
while(atoi(c_input) < 0)
{
cout<<"If you have a negative grade....drop out! otherwise enter another grade" << endl;
cin>>c_input;
}
while(c_input[0] != 'q')
{
while(atoi(c_input) < 0)
{
cout<<"If you have a negative grade....drop out! otherwise enter another grade" << endl;
cin>>c_input;
}
cout<<c_input;
cout<<"Would you like to enter another grade? or press q to quit" << endl;
cin>>c_input;
}
return 0;
}

Minimal, verifiable example:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int grade;
char quit = 'a';
cout << "Input your grade (0-100): ";
cout << endl;
cin >> grade;
while (quit != 'q') {
cout << " would you like to enter another grade? or press q to quit" << endl;
cin >> grade;
}
system("pause");
return 0;`enter code here`
}
See the problem with quit?
edit
What I have done is remove (most of) the lines that have nothing to do with quit or the loop.
At this point you should notice that the loop never changes quit.
If you are having trouble with a program, one of the best ways to figure out what is wrong is to get rid of everything that doesn't have anything to do with the error. In time, you'll be able to do this using only your mind. Duuude!
while i'm at it
The correct way to handle user input is to get it as a string, then convert it to what you want.
For example:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>
template <typename T>
T string_to( const std::string& s )
{
T value;
std::istringstream ss( s );
ss >> value >> std::ws;
if (!ss.eof()) throw std::invalid_argument("T string_to()");
return value;
}
int main()
{
std::cout << "Enter a number or 'q': ";
std::string s;
getline( std::cin, s );
if (s == 'q')
{
std::cout << "Good job! You entered 'q'.\n";
}
else
{
try
{
double x = string_to <double> ( s );
std::cout << "Good job! You entered '" << x << "'.\n";
}
catch (const std::exception& e)
{
std::cout << "Foo, you didn't obey instructions and made me " << e.what() << ".\n";
}
}
}

Related

Attempt at making a currency converter but it doesn't start at all

This is my final project for the semester. When I run it on replit, the program runs but doesn't work fully after the first step. When I run it on VS Code, it gives me a linker command error. This is due in 3 days, please any help is appreciated. Thank you
Below is my code:
`
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
const int HEAD_SPACE = 23;
const int SECND_HDSPACE = 35;
const int THRD_HDSPACE = 27;
char startKey;
char replayKey;
int userChoice;
int main()
{
float conversion(void);
firstStart:
cout << "=======================================================\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\t ::: CURRENCY CONVERTER :::\n\n";
cout << "=======================================================\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\tPlease select any options below\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\t1) Press [1] to convert from USD to GBP\n";
cout << setw(SECND_HDSPACE) << "\t\t\t2) Press [2] to convert from USD to EUR\n";
cout << setw(SECND_HDSPACE) << "\t\t\t3) Press [3] to convert from USD to NZD\n";
cout << setw(SECND_HDSPACE) << "\t\t\t4) Press [4] to convert from USD to JPY\n";
cout << setw(SECND_HDSPACE) << "\t\t\n\n :: PRESS [S] TO START PROGRAM :: \n\n";
menuOption:
cin >> startKey;
if(startKey == 's' && startKey == 'S')
{
float resultVal = conversion();
cout << "The conversion is: " << resultVal << endl;
cout << "Would you like to run the program again? Press Y or N" << endl;
scndStrt:
cin >> replayKey;
if (replayKey == 'y' && replayKey == 'Y')
{
goto firstStart;
}
else if ((replayKey == 'n' && replayKey == 'N'))
{
cout << "Thanks for using my program!" << endl;
}
else
{
cout << "Wrong Key Entered. Please hit Y or N" << endl;
goto scndStrt;
}
}
else
{
cout << "Wrong Key Entered. Please Hit [S]";
goto menuOption;
}
float convervion(void);
int selection;
int currChoice;
float currency1;
float currency2;
cout << "Please enter the currency name: " << endl;
cin >> selection;
cout << "Please enter the amount you would like to convert: " << endl;
cin >> currency1;
switch (selection)
{
case '1':
formulaInput:
cout << "Please enter what currency you would like to conver in: " << endl;
cin >> currency2;
if (currency2 == '1')
{
currency2 = currency1 * 1;
}
else if (currency2 == '2')
{
currency2 = currency1 * 0.84;
}
else if (currency2 == '3')
{
currency2 = currency1 * 0.94;
}
else if (currency2 == '4')
{
currency2 = currency1 * 1.92;
}
else
{
cout << "Incorrect input, please try again." << endl;
goto formulaInput;
}
}
}
`
I tried to watch some videos but the terminology and syntax seemed too advanced for me. I'm only a first year CS student and this is my first semester.
First of all, this program will not run correctly. But beside of that and to your question:
You have to close the main and open the conversion function(s). Check all your curly braces to be correctly.
Your function declaration is inside the main function. As retired Ninja in the comment section said, it is not incorrect and you can do this. Please think about local and global scope. (Within the main function it will become local scope for main and outside the declaration would be in global scope)
But if you think about it, if you wold define another function beneath the in local scope declared function, the same function will become global scope anyway. So for this reason it would be preferable to declare the function in global scope directly. For now, just from the standpoint, to avoid unnecessary irritation.
You have a misspell in your functions declaration and definition. (conversion / convervion ) please check this.
Your function is declared and defined with a return value of float but you forget the final return statement, which you will need to print out the calculation result.
.
#include <iostream> // Do you realy need all of these includes?
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <string>
using namespace std;
const int HEAD_SPACE = 23;
const int SECND_HDSPACE = 35;
const int THRD_HDSPACE = 27;
char startKey;
char replayKey;
int userChoice;
float conversion(void);
int main()
{
firstStart:
cout << "=======================================================\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\t ::: CURRENCY CONVERTER :::\n\n";
cout << "=======================================================\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\tPlease select any options below\n\n";
cout << setw(SECND_HDSPACE) << "\t\t\t1) Press [1] to convert from USD to GBP\n";
cout << setw(SECND_HDSPACE) << "\t\t\t2) Press [2] to convert from USD to EUR\n";
cout << setw(SECND_HDSPACE) << "\t\t\t3) Press [3] to convert from USD to NZD\n";
cout << setw(SECND_HDSPACE) << "\t\t\t4) Press [4] to convert from USD to JPY\n";
cout << setw(SECND_HDSPACE) << "\t\t\n\n :: PRESS [S] TO START PROGRAM :: \n\n";
menuOption:
cin >> startKey;
if (startKey == 's' && startKey == 'S')
{
float resultVal = conversion();
cout << "The conversion is: " << resultVal << endl;
cout << "Would you like to run the program again? Press Y or N" << endl;
scndStrt:
cin >> replayKey;
if (replayKey == 'y' && replayKey == 'Y')
{
goto firstStart;
}
else if ((replayKey == 'n' && replayKey == 'N'))
{
cout << "Thanks for using my program!" << endl;
}
else
{
cout << "Wrong Key Entered. Please hit Y or N" << endl;
goto scndStrt;
}
}
else
{
cout << "Wrong Key Entered. Please Hit [S]";
goto menuOption;
}
}
float conversion()
{
int selection;
int currChoice;
float currency1;
float currency2;
cout << "Please enter the currency name: " << endl;
cin >> selection;
cout << "Please enter the amount you would like to convert: " << endl;
cin >> currency1;
switch (selection) // ??
{
case '1':
formulaInput:
cout << "Please enter what currency you would like to conver in: " << endl;
cin >> currency2; // This is not working.
if (currency2 == '1')
{
currency2 = currency1 * 1;
}
else if (currency2 == '2')
{
currency2 = currency1 * 0.84;
}
else if (currency2 == '3')
{
currency2 = currency1 * 0.94;
}
else if (currency2 == '4')
{
currency2 = currency1 * 1.92;
}
else
{
cout << "Incorrect input, please try again." << endl;
goto formulaInput;
}
}
// Here you have to return something?
return currency2;
}

Why does This program have a logical error

this is the code i wrote for simple grading exams (im still a very beginner) but when i do a wrong input in (Grades) it doesnt go to the function i made which is called (FalseInput) to make the user able to re-enter the (Grades) any suggestions to how to solve?
and how to improve in general ?
here is an example of whats the problem :
Please Type Your Name : rafeeq
Please Insert The Grade : as (which is an input error)
you failed
thanks.
#include <iostream>
#include <string>
using namespace std;
char Name[30];
int Grades;
const int MinGrade(50);
void FalseInput() {
cout << "pleae enter the number again : ";
cin >> Grades;
if (Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << Grades;
} else if (Grades < MinGrade and cin.fail() == 0) {
cout << "you failed\n";
} else if (cin.fail() == 1) {
cout << "its not a valid number\n";
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
}
}
int main() {
cout << "Please Type Your Name : ";
cin.getline(Name, 30);
cout << "Please Insert The Grade : ";
cin >> Grades;
if (Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << "The Grade Achieved : " << Grades << "%";
} else if (Grades < MinGrade) {
cout << "you failed\n";
} else if (cin.fail() == 1) {
cout << "its not a valid number\n";
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
}
return 0;
}
You don't check if the extraction of an int succeeds here:
cin >> Grades;
You can check the state of the input stream after extraction like this and it needs to be the first condition or else the program will make the comparisons with MinGrade first and will get a true on Grades < MinGrade.
if(!(cin >> Grades)) {
if(cin.eof()) {
// You can't recover the input steam from eof so here you need
// to handle that. Perhaps by terminating the program.
}
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
} else if(Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << "The Grade Achieved : " << Grades << "%";
} else if(Grades < MinGrade) {
cout << "you failed\n";
}
You do have a lot of unnecessary code duplication and you also use an array of char to read the name - but you have included <string> so I assume you're familiar with std::string. I suggest using that.
Simplification:
#include <iostream>
#include <limits>
#include <string>
int main() {
const int MinGrade = 50;
std::string Name;
int Grades;
std::cout << "Please Type Your Name : ";
if(std::getline(std::cin, Name)) {
while(true) {
std::cout << "Please Insert The Grade : ";
if(!(std::cin >> Grades)) {
if(std::cin.eof()) {
std::cout << "Bye bye\n";
break;
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "That's not a valid number!\nPlease enter the "
"number again!\n";
} else if(Grades >= MinGrade) {
std::cout << Name << " : " << "you passed\n";
std::cout << "The Grade Achieved : " << Grades << "%\n";
break;
} else { // no need to check "Grades < MinGrade" here
std::cout << "you failed\n";
break;
}
}
}
}
What is happening: When that string "as" is attempted to write to the integer Grades, cin.fail() is set and Grades has the default of 0 written to it (I think that's right)
C++ cin reading string into int type returns 0
All-in-All: Input validation is needed BEFORE you check it's values.
Here is one approach, check if cin was able to successfully convert:
https://www.hackerearth.com/practice/notes/validating-user-input-in-c/
Another approach would be to read cin into a string instead of int, then you can control how to convert/cast it to whatever form you want (more work, but being that you are new - you will learn a lot doing this).
Secondary Note: Your string of 50 characters for name - imagine what would happen if you wrote 60 characters of input. There will be more data than the container can hold, thus writing past the bounds and into his neighbor (could cause a segment fault, or worse - crazy unexpected behavior)
Why does this work? Using cin to read to a char array smaller than given input

Still being prompted after entering a valid input value

I made this for an assignment but even if I enter a valid input from the desired range I still get prompted. This is happening to both input prompts. I suspect the problem is in the while blocks of the setupGame function.
#include <iostream>
using namespace std;
bool setupGame(int numberRef, int triesRef);
int main(){
cout<<"hello world";
setupGame(4,4);
cout<<"enough";
}
//SETUP GAME FUNCTION
bool setupGame(int numberRef, int triesRef) {
do {
cout << "ENTER A NUMBER BETWEEN 1 and 100" << endl;
cin >> numberRef;
cin.clear();
//your code here
cout << "You entered: " << numberRef << endl;
if (numberRef==-1) {
cout << "You do not want to set a number " << endl;
cout << "so you stopped the program" << endl;
}
else if(numberRef >=1 && numberRef <=100)
do {
cout << "ENTER TRIES BETWEEN 3 and 7" << endl;
cin >> triesRef;
cin.clear();
//cin.ignore( '\n');
cout<< "You entered: "<< triesRef<< endl;
if (triesRef==-1) {
cout << "You do not want to set tries. ";
cout << "so you stopped the program" << endl;
} else if(triesRef <= 3 && triesRef >= 7){
cout<<"Number of tries should be between 3 and 7";
}
}
while(numberRef >=1 && numberRef <=100);{
return true;
}
}
while(triesRef >= 3 && triesRef <= 7);{
return true;
} }
You're tangling yourself up with these nested loops. Your prompt keeps printing because the while loop:
while(numberRef >=1 && numberRef <=100)
is going to keep repeating it's preceding do block until you enter a value less than 1 or greater than 100, same goes for the last while loop as well.
I assume you're using cin.clear() to flush the previous input, if you are then stop it, that is not the purpose of cin.clear(). It's instead use to clear the error state of cin. Please thoroughly read up on it here.
Below is the code to achieve what you want, please observe how I implemented the while loops after each cin prompt to ensure that a valid character is entered.
#include <iostream>
#include <fstream>
using namespace std;
bool setupGame(int numberRef, int triesRef);
int main(){
cout<<"hello world";
setupGame(4,4);
cout<<"enough";
}
//SETUP GAME FUNCTION
bool setupGame(int numberRef, int triesRef) {
cout << "ENTER A NUMBER BETWEEN 1 and 100" << endl;
cin >> numberRef;
while((numberRef < 1 || numberRef > 100 || cin.fail()) && numberRef != -1) {
cin.clear(); // Used to clear error state of cin
cin.ignore(); // Might want to ignore the whole line
cout<<"Number should be between 1 and 100, or -1 , please try again: ";
cin>>numberRef;
}
cout << "You entered: " << numberRef << endl;
if (numberRef==-1) {
cout << "You do not want to set a number " << endl;
cout << "so you stopped the program" << endl;
}
if(numberRef >=1 && numberRef <=100) {
cout << "ENTER TRIES BETWEEN 3 and 7" << endl;
cin >> triesRef;
while(triesRef < 3 || triesRef > 7 || cin.fail()) {
cin.clear(); // Used to clear error state of cin
cin.ignore(); // Might want to ignore the whole line
cout<<"Tries should be between 3 and 7 , please try again: ";
cin>>triesRef;
}
cout<< "You entered: "<< triesRef<< endl;
if (triesRef==-1) {
cout << "You do not want to set tries. ";
cout << "so you stopped the program" << endl;
return false;
}
}
}

C++ loop error that my professor can't figure out

I am currently taking a C++ programming class and am working on a project in which I have to create a fairly simple movie database. My code essentially works as intended yet in certain cases it causes the main menu to loop infinitely and I cannot figure out why. I brought this to my teacher and he cannot explain it either. He gave me a workaround but I would like to know if anyone can see the cause of the problem. Full code is as follows:
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct MovieType
{
string title;
string director;
int year;
int length;
string rating;
};
MovieType addMovie() {
MovieType newMovie;
cout << "Movie title :";
getline(cin, newMovie.title);
cout << "Director :";
getline(cin, newMovie.director);
cout << "Year :";
cin >> newMovie.year;
cout << "Length(in minutes) :";
cin >> newMovie.length;
cout << "Rating :";
cin >> newMovie.rating;
cout << endl;
return newMovie;
}
void listMovie(MovieType movie) {
cout << "______________________________________" << endl;
cout << "Title : " << movie.title << endl;
cout << "Director : " << movie.director << endl;
cout << "Released : " << movie.year << endl;
cout << "MPAA Rating : " << movie.rating << endl;
cout << "Running time : " << movie.length << " minutes" << endl;
cout << "______________________________________" << endl;
}
void search(vector<MovieType> movieVector) {
string strSearch;
cout << endl << "Search title: ";
getline(cin, strSearch);
for (int c = 0; c < movieVector.size(); c++) {
if (movieVector.at(c).title == strSearch)
listMovie(movieVector.at(c));
}
}
int main() {
bool quit = 0;
vector<MovieType> movieVector;
while (quit == 0) {
char selection = 'f';
cout << "Main Menu:" << endl;
cout << "'a' - Add movie" << endl;
cout << "'l' - List movies" << endl;
cout << "'s' - Search by movie title" << endl;
cout << "'q' - Quit" << endl;
cout << "Please enter one of the listed commands:";
cin >> selection;
cin.ignore();
cout << endl;
if (selection == 'a')
movieVector.push_back(addMovie());
else if (selection == 'l') {
for (int c = 0; c < movieVector.size(); c++) {
listMovie(movieVector.at(c));
}
}
else if (selection == 's') {
search(movieVector);
}
else if (selection == 'q')
quit = 1;
}
return 0;
}
When an unexpected input type is entered during the addMovie function(like entering text for the int type year), it just runs through the function then loops through the menu infinitely. It appears to me that the code just stops even looking at the input stream. I have tried using cin.ignore() in many different places but it doesn't matter if there is nothing left in the stream it just keeps going.
I am using NetBeans to compile my code.
I really have no idea why it behaves like this otherwise I would offer more information but I am just curious as to why this happens, because as I said before, my professor doesn't even know why this is happening.
Any help or insight is greatly appreciated.
cin enters an error state where cin.fail() is true. In this state it just ignores all input operations. One fix is to clear the error state, but better, only use getline operations on cin, not formatted input.
E.g., instead of
cin >> newMovie.year;
… do
newMovie.year = stoi( line_from( cin ) );
… where line_from can be defined as
auto line_from( std::istream& stream )
-> std::string
{
std::string result;
if( not getline( stream, result ) )
{
// Throw an exception or call exit(EXIT_FAILURE).0
}
return result;
}
Disclaimer: code untouched by compiler.

Fahrenheit to Celsius converter. Verify int not char

Created a program to convert Fahrenheit to Celsius. Having trouble verifying if what the user input is an int. The problem I believe is the "if (!cin)" line.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
float f, c;
string choice;
do{
cout << "Enter a Fahrenheit temperature to convert to Celsius:" << endl;
cin >> f ;
if ( !cin ) {
cout << "That is not a number..." << endl;
}
else if (f < -459.67) {
cout << "That is not a Fahrenheit temperature..." << endl;
}
if ( f >= -459.67) {
c = (( f - 32) * 5.0)/9.0 ;
cout << fixed ;
cout << setprecision(2) << "Celsius temperature is: " << showpos << c << endl;
}
cout << "Would you like to convert another? If so, enter Yes" << endl;
cin >> choice ;
}while ( choice == "Yes" || choice == "yes" );
return 0;
}
I'm not sure of what you mean about your "Continue yes or no statement", So I've written a code that asks the user to type yes to confirm the conversion, otherwise no to enter a new Fahrenheit value. After the conversion, The program also asks the user to type yes if he/she wants another conversion, If the user types anything except "yes", The program will close.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
bool Continue = true;
while (Continue == true)
{
double f, c;
cout << endl << "Enter a Fahrenheit temperature to convert to Celsius:" << endl << endl;
while (!(cin >> f))
{
cout << endl << "Invalid Input. " << endl << endl;
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
while (f <= -459.67)
{
cout << "Invalid Input. " << endl;
cin.clear();
cin.ignore();
cin >> f;
}
cout << endl << "Continue? Type yes to proceed conversion, Otherwise type no." << endl << endl;
string confirmation;
cin >> confirmation;
while (confirmation != "yes" && confirmation != "no")
{
cout << endl << "Input not recognized. try again." << endl << endl;
cin >> confirmation;
}
if (confirmation == "yes")
{
c = ((f - 32) * 5.0) / 9.0;
cout << fixed;
cout << endl << setprecision(2) << "Celsius temperature is: " << showpos << c << endl;
cout << endl << "Another convertion? type yes to confirm. " << endl << endl;
string cont;
cin >> cont;
if (cont != "yes")
{
Continue = false;
}
}
}
return 0;
}
You should use while loop, So the program won't stop asking until the user enters the correct data. Use cin.clear(); to clear invalid data that the user inputted. And cin.ignore(); to ignore any succeeding erroneous data. For example, '25tg', 'tg' character is ignored since it's not valid. '25' will be accepted.
Edits in my answer and code provided are very welcome.
you can use a function to check if the input is numeric or not....
should be something like this:
bool isFloat( string myString ) {
std::istringstream iss(myString);
float f;
iss >> noskipws >> f; // noskipws considers leading whitespace invalid
// Check the entire string was consumed and if either failbit or badbit is set
return iss.eof() && !iss.fail();
}