My program keeps looping and I don't know why (c++) [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 months ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm a beginner in programming and I am currently trying to code things myself and I encountered a question that tells me to let a user choose from number 1-12 and it will display the month it represents (ex. 1=January) using while and switch loops. I'm now so brain dead need help.
edit: it loops if I entered a wrong input like putting a or 99.
#include <iostream>
using namespace std;
int main()
{
int months = 0;
cout << "Enter a number from 1-12 (or Q to quit): " << endl;
cin >> months;
while (months != 'Q')
{
switch (months){
case 1:
cout << "January" << endl;
break;
case 2:
cout << "February"<< endl;
break;
case 3:
cout << "March" << endl;
break;
case 4:
cout << "April" << endl;
break;
case 5:
cout << "May" << endl;
break;
case 6:
cout << "June" << endl;
break;
case 7:
cout << "July" << endl;
break;
case 8:
cout << "August" << endl;
break;
case 9:
cout << "September" << endl;
break;
case 10:
cout << "October" << endl;
break;
case 11:
cout << "November" << endl;
break;
case 12:
cout << "December" << endl;
break;
default:
{
cout <<"You've entered an invalid response. Please only select from numbers 1- 12.\n";
break;
}
}
}
//I hve no idea what to do here
return 0;
}

Two issues in your code:
First you read user input once outside of the loop. When the loop is executed once then it is executed forever, because the condition never changes. Move reading input inside the loop.
Second, you mixed up characters, char, and integers ,int. 'Q' is a character literal, its a char. 1,2, etc are integer literals, they are ints.
char is in fact also a number type, but specifically with input and output char is treated differently, because the "numbers" are treated as representations of characters. A common encoding is ASCII.
Pop quiz: What do you have to enter to make this code print foo on the console:
#include <iostream>
using namespace std;
int main()
{
int x;
std::cin >> x;
if (x == 'Q') std::cout << "foo\n";
}
Answer: It depends. With the usual ascii encoding 'Q' == 81 so you need to enter 81 to make x equal to 'Q'.
std::cin >> x reads an integer. If the user enters Q then reading an int will fail. std::cin will be in an error state and x will get 0 assigned.
Decide for one: Use an int then you cannot read user input Q. Or use char then you need to compare the input against the characters '1','2' etc.
Alternatively read a std::string and parse the input to see if it is a character or a number.

You need to take the input inside the while loop not outside it !
because the while loop depends on what the user will write
so you just need to correct it to this form
while (months != 'Q')
{
cout << "Enter a number from 1-12 (or Q to quit): " << endl;
cin >> months;
}
Update :
if the user writes an invalid input your program will go inside an infinite loop again so you should think about how to terminate it immediately after an invalid input

The problem is that you used while (months != 'Q'), not if (months != 'Q'). The compiler will always loop the while loop since months is always not equal to Q. Also, months is an int, i.e. inputting Q (this is not int) will crash your code, so you might want to modify it. You can either change Q into an int, or use char month and compare with '1', '2' etc.
#include <iostream>
using namespace std;
int main() {
int months;
cin >> months;
while (months != 'Q') {
cout << "Enter a number from 1-12 (or Q to quit): " << endl;
switch (months){
case 1:
cout << "January" << endl;
break;
case 2:
cout << "February"<< endl;
break;
case 3:
cout << "March" << endl;
break;
//etc. (i'll shorten the code here)
default:
cout << "Your input is invalid. Please only input numbers 1-12.\n";
break;
}
}
return 0;
}
PS: Please indent your code properly. You do not want your code to be a mess.

Let's rename the variable and use a lookup table (array).
static const char * month_names[] =
{
"No Month as 0",
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
int month_index = 0;
std::cout << "Enter month number: ";
std::cin >> month_index;
if ((month_index > 0) && (month_index < 12))
{
std::cout << "Month name is: " << month_names[month_index] << "\n";
}
else
{
std::cerr << "Invalid month number\n";
}
In the case of mapping a number to a name, arrays work very well. You can also search the array for the month name and the index will be the month number.

Related

Why does my code ignore a large chunk of itself? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 12 months ago.
Improve this question
hey I've just started on a school project but can't figure out why the code just ignores a large chunk of itself.
(also the code is part of a function inside of "math.h")
ill paste the whole segment here so that debugging it is easier.
#include <iostream>
#include <chrono>
#include <thread>
#include <algorithm>
using namespace std;
using namespace chrono;
using namespace this_thread;
class math {
private:
unsigned short pts;
public:
unsigned short questAmount;
char diff;
short arrEasy[4] = {1, 2, 5, 10}, secondVar, ans, studAns;
void questProc() {
start:
cout << "How hard do you want the questtions to be?" << endl;
cout << "(The harder you choose, the larger the numbers you'll have to calculate)" << endl;
cout << "1) EASY" << endl;
cout << "2) MEDIUM" << endl;
cout << "3) HARD" << endl;
cout << "4) CALCULATOR MODE LOL" << endl << "~> ";
cin >> diff;
switch (diff) {
case '1':
system("cls");
cout << "EASY MODE ACTIVATED" << endl;
break;
case '2':
system("cls");
cout << "MEDIUM MODE ACTIVATED" << endl;
break;
case '3':
system("cls");
cout << "HARD MODE ACTIVATED" << endl;
break;
case '4':
system("cls");
cout << "CALCULATOR MODE ACTIVATED" << endl;
break;
default:
system("cls");
cout << "INPUTED VAL IS EITHER NOT AN INT OR ISN'T IN THE LIST"; //checks only the starting int ignores the rest...
sleep_for(0.5s); cout << "."; sleep_for(0.5s); cout << "."; sleep_for(0.5s); cout << "."; sleep_for(0.5s);
break;
if (diff != 1 && diff != 2 && diff != 3 && diff != 4) { goto start; }
}
// The following creates the question according to the set difficulty.
srand(time(NULL)); // Initializing random seed.
switch (diff) {
case 1: // Easy Mode:
system("cls");
random_shuffle(&arrEasy[0], &arrEasy[4]); // For first var.
secondVar = rand() % 10 + 1; // Rand number from 1 to 10 (for second var).
ans = arrEasy[0] * secondVar;
cout << arrEasy[0] << " * " << secondVar << " = ?" << endl << "~> ";
cin >> studAns;
break;
default:
break;
}
// The following checks if ans is correct.
if (studAns == ans) {
cout << "WELL DONE!";
}
else {
cout << "WRONG, CORRECT ANSWER WAS:" << ans;
}
}
};
I wanted it to continue on to actually calculate the question and to then check if I was right or not...
here's what I got instead:
How hard do you want the questtions to be?
(The harder you choose, the larger the numbers you'll have to calculate)
1) EASY
2) MEDIUM
3) HARD
4) CALCULATOR MODE LOL
~> 1
and then:
EASY MODE ACTIVATED
WELL DONE!
that's all it says, despite all the other things its also supposed to do...
ps. tell me if you need any more info.
Because of type mismatch!
you defined "diff" as a char and use it as such in your switch statement. However, in your second switch statement, you remove the quotes and use it as a number. That causes a char to int conversion according to the ascii table.
Look at the decimal field, the number 1 as an int corresponds to a non-printable character that you will rarely see in real life. The character '1' corresponds to 49.
Solution:
switch(diff){
case '1': //notice the quotations
//rest of code
break;
}
for this line
if (diff != 1 && diff != 2 && diff != 3 && diff != 4) { goto start; }
you mean
if (diff != '1' && diff != '2' && diff != '3' && diff != '4') { goto start; }
given that diff is a typed in char not an int

Code skips next cin after leaving function

I am working on a little text based adventure game, the first project I've ever worked on for my own enjoyment, and have ran into a problem. I have got it to ask if you want to play, what your name will be and then the problem starts when you try to choose a race. It works just fine when the user types the first character but when they type the string it will skip past the gender, and class cin. Do I have to clear the cin? Or is my code just wrong?? Thanks for any help you can provide.
#include "pch.h"
#include <iostream>
#include <string>
#include <cctype>
#include <map>
using namespace std;
enum races { Human, Orc, Elf, Dwarf};
enum classes { Warrior, Mage, Archer, Assassin};
const std::map< char, string > race_map =
{ {'H', "human"}, {'O', "orc"}, {'E', "elf"}, {'D', "dwarf"} };
const std::map< char, string > class_map =
{ {'W', "warrior"}, {'M', "mage"}, {'Ar', "archer"}, {'A', "assassin"}
};
void gameIntro();
void gameStart();
void raceFunc(char race);
void playerClassFunc(char playerClass);
void gameIntro()
{
string playerName;
char race;
char sex;
char playerClass;
cout << "Enter your name: \n";
cin >> playerName;
cout << "\n";
cout << "Select a race (Human, Orc, Elf, Dwarf): \n";
cin >> race;
cout << "\n";
raceFunc(race);
cout << "Select Gender (M or F): \n";
cin >> sex;
cout << "\n";
cout << "Select a class (Warrior, Mage, Archer, Assassin): \n";
cin >> playerClass;
cout << "\n";
playerClassFunc(playerClass);
gameStart();
}
void raceFunc(char race)
{
race = toupper(race);
switch (race)
{
case 'H':
cout << "You chose Human!\n\n";
break;
case 'O':
cout << "You chose Orc!\n\n";
break;
case 'E':
cout << "You chose Elf!\n\n";
break;
case 'D':
cout << "You chose Dwarf!\n\n";
break;
default:
cout << "Please choose from the following. Program closing.\n";
system("pause");
exit(0);
}
}
void playerClassFunc(char playerClass)
{
playerClass = toupper(playerClass);
switch (playerClass)
{
case 'W':
cout << "You chose Warrior!\n";
break;
case 'M':
cout << "You chose Mage!\n";
break;
case 'Ar':
cout << "You chose Archer!\n";
break;
case 'A':
cout << "You chose Assassin!\n";
break;
default:
cout << "Please choose from the following. Program closing.\n";
system("pause");
exit(0);
}
}
void gameStart()
{
}
int main()
{
char answer;
cout << "Welcome to Dark Horse\n\n";
cout << "This is my fisrt ever actual program I made out of my own free
will lol.\n";
cout << "It is a Text-Based Adventure game. In this game you will make a
character,\n";
cout << "and explore the land of Spelet, battling enemies, leveling up,
getting loot,\n";
cout << "and learning skills! You do not need to capitalize anything but
your character\n";
cout << "name. If a question has (something like this) if you don't
enter whats inside\n";
cout << "the program will CLOSE, so please pay attention! Thank you for
trying it out!\n";
cout << "I really hope y'all enjoy it!\n\n";
do
{
cout << "Would you like to play?\n";
cin >> answer;
if (answer == 'Y')
{
gameIntro();
}
else if (answer == 'N')
{
system("pause");
return 0;
}
else if (answer != 'N' || 'Y' || 'exit')
{
cout << "Come on dog it's Y or N...yes or no...\n\n";
}
} while (answer == 'N' || 'Y');
system("pause");
return 0;
}
"cin, of class istream, is the standard input channel used for user input. This steam corresponds to C's stdin. Normally, this stream is connected to the keyboard by the operating system." (Josuttis, 2012, p. 745)
Josuttis, N. (2016). The C++ Standard Library: A Tutorial and Reference 2nd Edition: Addison-Wesley
The types are important.
char race;
std::cout << "Please enter your race:" << std::endl;
std::cin >> race;
If the user enters "Human", the standard input stream contains Human and the race variable now has the value H (of type char). The standard input stream now contains uman.
char gender;
std::cout << "Please enter your gender:" << std::endl;
std::cin >> gender;
Calling >> with std::cin gets another character from the standard input stream (in this case u) and stores it in gender. The standard input stream now contains man.
While it appears that the gender question was skipped, you can now see that this is not the case. The input stream still contains characters. If you look at your first screenshot you can see that "Mage" was selected. This is because the value of playerClass is m, the same m from when you entered human.
One way to remedy this is to use std::string instead of char to store the input. That way you have more flexibility in parsing what the user enters (e.g. you can allow for H or Human).

Is there a way to input different value for the same data when the same function is called multiple times?

I'm creating a student data management program in C++ and the function to insert examination marks is buggy.
The code given below is enough to recreate the buggy part of the program.
I have tried to increase the size of sub[] to 16
I have tried to insert data one after the other instead of a loop
None of the above seem to solve the problem
Menu function:
char ch;
main_menu:
clrscr();
cout << "Press the key for your choice:\n";
cout << "D -> Edit details\n";
cout << "R -> Get result\n";
cout << "I -> Insert marks\n";
cout << "E -> Exit Program";
choice:
ch = getch();
switch(ch)
{
case 'd':
//edit_nam(); Ignore this one
goto main_menu;
break;
case 'i':
ins_mar();
goto main_menu;
break;
case 'r':
//get_res(); This one is not related to the problem
goto main_menu;
break;
case 'e':
break;
default:
goto choice;
}
Insert marks function:
for(int i = 0; i < 6; i++)
{
clrscr();
cout << "Enter details of subject:" << i + 1;
cout << "\nSubject name:";
cout << "\nMarks:";
gotoxy(14, 1);
cin.getline(student.marks[i].sub, 8);
gotoxy(7,2);
cin >> student.marks[i].mark;
(i != 5) ? cout << "\nPress any key to continue..." : cout << "\nPress any key to return to menu...";
getch();
}
Student structure:
struct stu
{
char name[20];
int ID;
int cls;
mar marks[6];
};
Marks structure:
struct mar
{
char sub[8];
float mark;
}
If the code was working fine, then it would ask the user to enter the marks for all six subjects, every time the function is called in one run.
However, It is not so. In the first time of function call, everything happens in the correct manner, but it does not ask for subject name after first subject in any of the other runs.

Where should i put a do while bool is true

I wrote a program that outputs the name equivalent of a numerical grade the user wrote into the console.
1 being FAIL
2 being SATISFACTORY
3 being GOOD
4 being VERY GOOD
5 being EXCELLENT
Now I would like to ask the user does he want to continue inputting the grades AFTER the first one runs,
e.g
input grade
-> 5
Excellent
Would you like to continue inputting grades? 1 - yes/ 0 -no
I'm clueless where to put the do while bool is true..
int main()
{
int grade;
do
{
cout << "input your grade: \n";
cin >> grade;
if (grade < 1 || grade > 5)
{
cout << "input grade again!\n";
}
} while (grade < 1 || grade > 5);
switch (grade)
{
case 1:
cout << "fail\n";
break;
case 2:
cout << "satisfactory\n";
break;
case 3:
cout << "good\n";
break;
case 4:
cout << "very good\n";
break;
case 5:
cout << "excellent\n";
break;
}
return 0;
}
You just need another do-while statement to have a repeated process. I've initialized a char variable named userChoice (always make the initialization to avoid undefined behaviors and hard to track errors) to check in every iteration what user wants (to continue or to end the program).
//previous codes...
char userChoice = 'n';
do{
// previous codes which you want to be repeated
std::cout << "\nDo you want to continue ? (y = Yes, n = No ) "; // ask the user to continue or to end
std::cin >> userChoice; // store user's input in the userChoice variable
}while(userChoice); // if user's input is 'y' then continue with next iteration
//rest of the code...
Also, Why is "using namespace std" considered bad practice?

String input in a function within a switch-case statement results in infinite loop and bypassing of input? [duplicate]

This question already has answers here:
Why would we call cin.clear() and cin.ignore() after reading input?
(4 answers)
Closed 5 years ago.
Novice trying to self teach himself C++ here.
Here is the code for reference:
#include <iostream>
void function1(int);
void function2(int);
void function3(int);
using namespace std;
int main() {
int input = 0;
while (input != 4){
cout << "Prompt" << endl;
cin >> input;
switch(input) {
case 1:
function1(input);
break;
case 2:
function2(input);
break;
case 3:
function3(input);
break;
case 4:
cout << "Program terminated." << endl;
return 0;
break;
default:
cout << "Invalid input." << endl;
input = 4; // Exits the while-loop.
break;
}
}
}
void function1(int a) {
int prompt;
cout << "Prompt again" << endl;
cin >> prompt;
if (!cin){
cout << "Input is not a number." << endl;
return;
}
}
void function2(int a) {
}
void function3(int a) {
}
What I'm trying to do is make a function1 that detects if a specific input was a string or a char instead of an integer, and then say that it is not a number, then go back to the switch case statements. Once it detects this though, the statements in the while loop go on forever and completely bypass the cin prompts! I understand from reading other people's questions that the infinite looping might have something to do with using 'int' in a header and inputting a string when an integral is expected, but I don't understand why the code doesn't stop when the cin is prompted or how to bypass it. Any help?
if (!cin){
cout << "Input is not a number." << endl;
return;
}
When cin<< reads a bad input, its flags are set to an error state. The error state needs to be cleared by resetting the flags to zero, which is done using cin.clear(). Change your if-statement to include the cin.clear() statement:
if (!cin){
cout << "Input is not a number." << endl;
cin.clear(); // <-- Add this line
return;
}
When you enter invalid input for cin <<, the error flags of cin<< are set to 1 (true). That is why we use cin.clear(); so that the error flags are reset to zero, and cin<< can accept new input.