Program outputs incorrect numbers from array - c++

Jeopardy point adding code.
The program is supposed to get the number of players with a dynamic array.
From there, you can enter players names and it will insert the names into a two-dimensional array.
Then you can choose to call on a player to start adding points to.
After looping a certain amount of times and pressing 0, the while loop will cease to run and will skip down to the for loop outputting players name and then points.
Problem: If I input "1" for playerNumber, and I start adding points to index [0][1] and outputs numbers quite different from the original numbers I put in. If there are more than 2 players, 2 of the 3 players have random numbers while one remains an accurate point count.
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
//GLOBAL SCOPE, all loops and other boxes can use these
//Declaration variables w cout & cin.
int playerNumber;
string playerNames;
bool flag = true;
cout << "How many players are there: ";
cin >> playerNumber;
cout << endl;
//Array Declaration.
string playerList[playerNumber][2]; //Dynamic array. changes during program runtime.
int points[playerNumber]; //Dynamic array. Changes during runtime
//GLOBAL SCOPE, all loops and other boxes can use these
//Assigning values to arrays now.
cout << "Enter the players names: " << endl;
//Assigns player name to each row.
for(int i = 0; i < playerNumber; i++){
cin >> playerNames;
playerList[i][0] = playerNames; //Assigns players name to the array
cout << "Player " << i + 1 << ": " << playerList[i][0] << endl;
}
while(flag){
//LOCAL VARIABLES
int choice = 0; //Always reverts back to zero to prevent addition error.
int pointsValue = 0; //Always reverts back to zero to prevent addition error.
//LOCAL VARIALES
cout << "Press 0 to end game, if not, enter player number: " << endl;
cin >> choice;
if(choice == 0){ //Exit out of the while loop
flag = false;
}
else if(cin.fail()){
cout << "Not a number. Try again." << endl;
cin.clear();
cin.ignore(256, '\n');
}
else if(choice < 0 || choice > playerNumber){
cout << "Choice is less than 0 or greater than player count. Try again." << endl;
}
else{
cout << "Enter points: " << endl;
cin >> pointsValue;
cout << endl;
points[choice - 1] += pointsValue; //Assigns points to points array
playerList[choice - 1][1] = (to_string(points[choice - 1])); //Assigns points to playerNumber.
}
}
cout << endl;
cout << "END OF JEOPARDY. HERE ARE THE POINTS!!!" << endl;
cout << endl;
//Current points for each player
//Shows their name and points
for(int i = 0; i < playerNumber; i++){ //Loops so that player name and points are displayed
string playerName = playerList[i][0];
string totalPoints = playerList[i][1];
cout << playerName << " points: " << totalPoints << endl;
}
return 0;
}

Technically, this is illegal:
string playerList[playerNumber][2];
int points[playerNumber];
The size of the array must be known at compile time (not runtime). Though some compilers allow this as an extension to the language, it is not part of the standard language.
Better choice would have been to use std::vector.
Lets assume your compiler allows this:
The next issue is that you don't initialize the values in the array.
int points[playerNumber]; // This is an array of random numbers.
// Sure if you are doing a debug build the
// compiler may be nice and just set all the
// values to zero as speed is not important
// during debugging. But on a release build
// these could be any value.
Also if we want to be technical its actually undefined behavior to read from the array unless you first write a value. Though usally this is not going to cause the program to crash on most architectures and unfortuantely the code just runs like nothing bad is happening.
You can normall initialize the array like this:
int points[10] = {0}; // but your variable size stuff
// will stop working for that.
-------
// so you will have to manually initialize the members
int points[playerNumber];
for(int loop = 0; loop < playerNumber; ++loop) {
points[loop] = 0;
}
Or if you upgrade to vector:
std::vector<int> points(playerNumber,0); // Size and initial value.
// Though you don't need the
// initial value as vector will
// zero init members.
The last issue I will mention is that you are not consistent on checking if the read worked.
cin >> pointsValue;
What do you think happens to pointsValue if the read fails (ie. the user puts in an illegal value). The proper way to check the user input is to put the read inside an if statement.
if ( std::cin >> pointValue) {
// The read worked `pointsValue` has valid user input
}
else {
// The read faild.
// We don't know what the user input should be
}
The other thing to think about is that user input is line based. They add values hit return. So it is a good tactic to exploit that and read user input by the line. Once you have the line parse that and validate input. That way the standard input stream does not go into a bad state.
std::string line;
if (std::get(std::cin, line)) {
// We have a line of user input.
std::stringstream lineStream(std::move(line));
line.clear();
int choice;
if (lineStream >> choice) {
// We have a valid choice from the user.
// or do we. If the user entered `2x` is that valid input?
// because `choice` is 2; but there is still `x` on the
// input stream.
// That's a choice for you as the developer to make.
// if you don't care, then you have valid input. If you do
// care then you need to check there is no bad data on
// the line.
}
else {
// invalid choice
}
}
else {
// The user input stream just ended.
// This could mean the user entered the end-of-stream character
// or if the user had connected some other stream to the
// standard input on the command line and there is no more
// data to read.
}
I would note that this will probably never work for invalid input.
if(choice == 0){ //Exit out of the while loop
flag = false;
}
else if(cin.fail()){
// If you failed to read data from the std::cin
// the the value of `choice` is probably zero
// (if I remember my standard correctly) so the
// first branch of the if tree will be entered
// and you will never enter this branch.
cout << "Not a number. Try again." << endl;
cin.clear();
cin.ignore(256, '\n');
}

Related

Infinite loop created when inputting "yy" into a char variable that should only take a single character such as 'y' or 'n', "nn" does not break code

The code in the cont function asks the user if they want to play my game again.
The code works when receiving proper character inputs such as 'y' or 'n' as well as their respective capital letter variants, and the else block works properly to loop the function if an invalid input such as 'a' or 'c' is entered.
However during a test run, an input of 'yy' breaks the code causing the program to infinitely loop, running not only this cont function but my game function as well.
choice is stored as a char variable. I am wondering why the code even continues to run upon inputting multi-character inputs such as 'yy' or 'yes'. What's interesting is 'nn', 'ny' and other variations of multi-character inputs that begin with 'n' causes no issues and properly results in the else if block running as intended. Which prints "Thanks for playing." then ends the program.
Can variables declared as char accept inputs greater than 1 character? Does it only take the first value? And if so why does 'yy' cause a loop rather than the program running as intended by accepting a value of 'y' or 'Y'? How can I change my program so that an input of 'yy' no longer causes issues, without specific lines targeting inputs such as 'yy' or 'yes'.
#include <iostream>
#include <string> // needed to use strings
#include <cstdlib> // needed to use random numbers
#include <ctime>
using namespace std;
// declaring functions
void cont();
void game();
void diceRoll();
// variable declaration
string playerName;
int balance; // stores player's balance
int bettingAmount; // amount being bet, input by player
int guess; // users input for guess
int dice; // stores the random number
char choice;
// main functions
int main()
{
srand(time(0)); // seeds the random number, generates random number
cout << "\n\t\t-=-=-= Dice Roll Game =-=-=-\n";
cout << "\n\nWhat's your name?\n";
getline(cin, playerName);
cout << "\nEnter your starting balance to play with : $";
cin >> balance;
game();
cont();
}
// function declaration
void cont()
{
cin >> choice;
if(choice == 'Y' || choice == 'y')
{
cout << "\n\n";
game();
}
else if (choice == 'N' || choice == 'n')
{
cout << "\n\nThanks for playing.";
}
else
{
cout << "\n\nInvalid input, please type 'y' or 'n'";
cont(); // calls itself (recursive function!!!)
}
}
void game()
{
do
{
cout << "\nYour current balance is $ " << balance << "\n";
cout << "Hey, " << playerName << ", enter amount to bet : $";
cin >> bettingAmount;
if(bettingAmount > balance)
cout << "\nBetting balance can't be more than current balance!\n" << "\nRe-enter bet\n";
} while(bettingAmount > balance);
// Get player's numbers
do
{
cout << "\nA dice will be rolled, guess the side facing up, any number between 1 and 6 : \n";
cin >> guess;
if(guess <= 0 || guess > 6 )
{
cout << "\nYour guess should be between 1 and 6\n" << "Re-enter guess:\n";
}
} while(guess <= 0 || guess > 6);
dice = rand() % 6+1;
diceRoll();
if (dice == guess)
{
cout << "\n\nYou guessed correctly! You won $" << (bettingAmount * 6);
balance = balance + (bettingAmount * 6);
}
else
{
cout << "\n\nYou guessed wrong. You lost $" << bettingAmount << "\n";
balance = balance - bettingAmount;
}
cout << "\n" << playerName << ", you now have a balance of $" << balance << "\n";
if (balance == 0)
{
cout << "You're out of money, game over";
}
cout << "\nDo you want to play again? type y or n : \n";
cont();
}
void diceRoll()
{
cout << "The winning number is " << dice << "\n";
}
Does it only take the first value?
Yes, the >> formatted extraction operator, when called for a single char value, will read the first non-whitespace character, and stop. Everything after it remains unread.
why does 'yy' cause a loop
Because the first "y" gets read, for the reasons explained above. The second "y" remains unread.
This is a very common mistake and a misconception about what >> does. It does not read an entire line of typed input. It only reads a single value after skipping any whitespace that precedes it.
Your program stops until an entire line of input gets typed, followed by Enter, but that's not what >> reads. It only reads what it's asked to read, and everything else that gets typed in remains unread.
So the program continues to execute, until it reaches this part:
cin >> bettingAmount;
At this point the next unread character in the input is y. The >> formatted extraction operator, for an int value like this bettingAmount, requires numerical input (following optional whitespace). But the next character is not numerical. It's the character y.
This results in the formatted >> extraction operator failing. Nothing gets read into bettingAmount. It remains completely unaltered by the >> operator. Because it is declared in global scope it was zero-initialized. So it remains 0.
In addition to the >> extraction operator failing, as part of it failing it sets the input stream to a failed state. When an input stream is in a failed state all subsequent input operation automatically fail without doing anything. And that's why your program ends up in an infinite loop.
Although there is a way to clear the input stream from its failed state this is a clumsy approach. The clean solution is to fix the code that reads input.
If your intent is to stop the program and enter something followed by Enter then that's what std::getline is for. The shown program uses it to read some of its initial input.
The path of least resistance is to simply use std::getline to read all input. Instead of using >> to read a single character use std::getline to read the next line of typed in input, into a std::string, then check the the string's first character and see what it is. Problem solved.
cin >> bettingAmount;
And you want to do the same thing here. Otherwise you'll just run into the same problem: mistyped input will result in a failed input operation, and a major headache.
Why do you need this headache? Just use std::getline to read text into a std::string, construct a std::istringstream from it, then use >> on the std::istringstream, and check its return value to determine whether it failed, or not. That's a simple way to check for invalid input, and if something other than numeric input was typed in here, you have complete freedom on how to handle bad typed in input.

how to store data into dynamic array

I have this program that asks user to enter a number and ask the user if they want to view input history. So i was wondering if my code is correct. I want to know if doing cin>>num[count-1] is correct or is there a correct way to get the data the user inputs. Here it is:
#include<iostream>
using namespace std;
int main(){
const int size = 20;
int *num = new int[size];
char answer;
int count = 1;
while(true){
cout<<"ENTER NUMBER: \n";
cin>>num[count-1];
cout<<"TRY AGAIN? ";
cin>>answer;
switch(answer){
case 'y':
count++;
system("cls");
break;
default:
cout<<"INPUT HISTORY: \n";
for(int i=0;i<=count-1;i++){
cout<<num[i]<<endl;
}
count++;
}
}
delete [] num;
return 0;
}
I want to know is doing cin>>num[count-1]` is correct or is there a correct way to get the data the user inputs.
Your code is a c-style code. You have the std::array and std::vector to help you to write a more secure and clean code. Because your tag in your question is dynamic-arrays I suggest to use the std::vector.
Bellow you can check out your code could be with the replacement.
#include <iostream>
#include <vector>
using namespace std;
int main() {
//int *num = new int[size]; //normally you don't need to use new. Let the c++ manage it for you
vector<int> num;
char answer;
while (true) {
cout << "ENTER NUMBER: \n";
num.emplace_back(); //Create a new element to vector num
cin >> num.back(); //set this new element
cout << "TRY AGAIN? ";
cin >> answer;
if (answer == 'y')
system("cls");
else {
cout<<"INPUT HISTORY: \n";
for (auto& numEle : num) //It will interate over all elements of num
cout<< numEle <<endl;
//break; //Maybe you want to break the loop here
}
}
// delete [] num;
return 0;
}
I will first show you the problems in your code. I put in comments.
Then I will explain you, why your input is wrong. Also the answer from user TheArquitect is wrong and will finally lead to a memory overflow.
Your program will also have a desastrous result.
First see the code:
#include<iostream>
using namespace std; // In C++ we never use this statement. Why? See:
// You will find at least 1000 comments in Stackoverflow
int main() {
const int size = 20; // In C++ we use constexpr for compile time constants
int* num = new int[size]; // In C++ we
// Do not use raw pointers for owned memory
// Do not use new
// Do Not use C-Style arrays
// Generally: std::vector should be used
// Or at least std::unique_ptr and std::make_unique
// Also, this 2 lines are nonesense. It is the same as int num[20];
char answer; // All variables should always be initialized
// Variables should be in the scope, where they are necessary
int count = 1; // YOu could use uniform initialization
// Arrays start with index 0 in C++ (also in C )
while (true) { // You are creating an endless loop with desastrous effect
cout << "ENTER NUMBER: \n";
cin >> num[count - 1]; // No, this will not work. Explanation in text
cout << "TRY AGAIN? ";
cin >> answer; // No, this will not work. Explanation in text
switch (answer) { // Switch with only one case can always be expressed with if elese
case 'y':
count++;
system("cls"); // This is a non portable solution
break;
default:
cout << "INPUT HISTORY: \n";
for (int i = 0; i <= count - 1; i++) { // Nearly Never use <= in for loops
// Use for (int i = 0; i < count; i++)
// Do use ++i insted of i++
cout << num[i] << endl;
}
count++;
} // This is an endless loop. count will always be increased. If greater than 20
// then the memory will be corrupted. This will happen always
}
delete[] num; // Dead code. Will never be invoked
return 0;
}
OK. Now, besides the major bugs and the killing out of bounds problem, here the explanation for the problem with inputting data.
Rule: You must always check, if the input operation worked. For that you can check the state of the stream. Additionally, if you do not consume the input data (because of an erronous input by the user), this data is still in the input buffer. And in the next loop it will be read again (without waiting for new user input). The status of the input stream may still be wrong and it will also not read because of this.
Then the endless loop starts to run without user input and corrupts your memory.
You may check, by simply inputting a letter instead of a number.
How to fix?
Again, you must check the state of the stream after reading. This is usually done in the form:
if (std::cin >> number)
Why does this work? Because: The inserter operator returns a reference to the stream (so std::cin) and the boolean '!' not-operator for the std::istream is overwritten. It will show, if the state of the stream is still ok or not.
OK, understood. Now. What to do in case of error? 2 operations:
Clear all failure bits in the state of the stream --> std::cin.clear()
Eat up everything that is still in the input buffer --> std::cin.ignore()
You could write:
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
I assume that you are learing C++ in a class and learn about new and delete. As said, you should not use it. But because teacher request this often in the classes, I will show you now a better solution than yours, still using new, but without (most of) the problems.
#include<iostream>
#include <limits>
int main() {
// We want to create a dynamic array with 20 elements
constexpr size_t MaxArraySize{ 20U };
// Allocate a dynamic arry on the heap
int* numberArray = new int[MaxArraySize];
// Read maximum 20 numbers into our dynamic array
for (size_t currentArrayIndex{}; currentArrayIndex < MaxArraySize; ) {
// Inform the user that he should ent now a number
std::cout << "Enter number: \n";
// Read the number and check, if this worked
if (std::cin >> numberArray[currentArrayIndex]) {
// Now ask, if the user wants to continue or stop
std::cout << "Doy you want to enter more numbers? ('y' or 'n'): ";
// Define variable answer and get user input and check, if ok
if (char answer{}; std::cin >> answer) {
// Does the user want to continue?
if ('y' == answer) {
// Yes, continue. Increment array index
++currentArrayIndex;
}
else {
// No, the user does not want to continue. Show the values entered so far
std::cout << "Input History:\n";
for (size_t i{}; i <= currentArrayIndex; ++i) { // NOTE: <= becuase index has not yet been incrementet
std::cout << numberArray[i] << "\n";
}
break; // Stop the for loop and end the program
}
}
else {
// Strange, input of a character did not work. Should not happen. Terminate program
std::cerr << "\n*** Error: Problem with input!\n\n";
break; // Stop the for loop and end the program
}
}
else {
// The user entered someting wrong, or the input did not work for any other reason
// Inform user about problem
std::cerr << "\n*** Error: No number could be read!\n\n";
// Clear error flag and comsume whatever is in the input buffer
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
// Release dynamic allocated memory
delete[] numberArray;
return 0;
}

Need some help finding a logical error in my while loop

I am learning C++, and I am doing some exercises in the book I am using. One of them asks to write a program that asks a user how many numbers they want to add up. Then prompt for the numbers the user wants to add or to enter '|' once finished. The numbers are then pushed into a vector. Part of the program asks to check if the size of the vector is equal to the original number of input items and that is where I keep getting an error.
cout << "Please enter the numbers and | once you are done: ";
while(true)
{
for(int num; cin >> num; )
{
if(num == '|')
{
break;
}
ints.push_back(num);
}
if(ints.size() != n)
{
cout << "There are more or less numbers in the vector than originally specified\n"
<< "Vector will be cleared; please re-enter the values: ";
ints.clear();
continue;
}
else
{
break;
}
}
The problem is that if the number of input is off, the message goes into an infinite loop and I am not sure how to fix it.
EDIT: n is the variable that holds in the number of values user wanted to enter.
Thanks!
num is an integer and cin >> num won't extract | symbol. Comparison num == '|' may not work as expected because num could have the numeric value of | ascii symbol even when user did not input any | symbol. You should properly handle end marker reading:
// loop will break when user enters `|` because it is not an integer
// setting failbit of cin
for(int num; cin >> num;)
{
ints.push_back(num);
}
cin.clear(); // reset failbit making cin able to read again
// check the end marker entered by user
{
string end_marker;
cin >> end_marker;
if("|" != end_marker)
{
// use of endl will flush the stream ensuring that
// printed text won't stuck in the buffer
cout << "Please use | as end marker" << endl;
continue;
}
}
Here is how I implemented it. I am worried about the logic in your while loop. I had been taught to avoid while(true) whenever possible. You know the logic behind how your code should work. With more practice you'll start to recognize the conditions you need to use. I am sure there are better ways to do it. But this is the way I tried it.
But to answer your question, the main reason it is failing is because integers cannot compare themselves with characters.
if(num == '|')
That does not work since num is an integer and not a character.
Normally I would implement this in a class and since global variables are not highly looked upon I created my own namespace. You'll have to finish the rest of the logic yourself however:
#include <iostream>
#include <vector>
#include <string>
namespace global
{
std::vector<std::string> strings;
std::vector<int> ints;
std::string a = " ";
int num = 0;
}
void doWork()
{
std::cout << "Please enter the number of integers you would like to add up: ";
std::cin >> global::num;
std::cout << "Please enter the numbers and | once you are done: ";
while (global::a != "|")
{
std::cin >> global::a;
global::strings.push_back(global::a);
}
global::strings.pop_back();
for(auto &e : global::strings)
{
global::ints.push_back(std::stoi(e));
}
}
int main()
{
doWork();
if(global::ints.size() != global::num)
{
std::cout << "Size of vector does not match the size specified. Clearing vector" << std::endl;
global::ints.clear();
global::strings.clear();
global::num = 0;
global::a = " ";
doWork();
}
}
I made a vector of char's and converted those into integers so that way you could add them up. The while loop should be checking for | rather than always running true. It then will check the size of the vector in the end, clear it if it does not match, and ask you to do it again. This is the best way that I could think of doing it.
EDIT: as VTT pointed out, char can only do one character at a time. I have converted it into a string in order to handle the conversion.
EDIT 2: reset the values of global::num and global::a to their default at the end of the failure in order to prevent crashing.

do loop statement is causing an infinite loop

I am writing a library program that displays a menu of options letting the user add new books to the library, but in my add statement it accepts the title and then gets caught in an infinite loop. I wrote a book class that mainly uses pointers to assign things, if I need to post that I will. But when you run the program it compiles, displays the menu, and when you choose add a book it accepts the title but as soon as you hit enter it starts an a infinite loop.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
int main()
{
int bookCounter = 0;
Book library[25];
int menuOption = 0;
char tempt[50] = "\0";
char tempauth[50] = "\0";
char search[50] = "\0";
unsigned int tempp = 0;
do
{
menuOption = 0;
cout << endl << "1. Show the Library" << endl;
cout << "2. Add a Book" << endl;
cout << "3. Search the Library by Title" << endl;
cout << "4. Exit Library" << endl;
cout << "Select a menu option (e.g. 1, 2, etc.): ";
cin >> menuOption;
if(menuOption == 1)
{
for(int i = 0; i < bookCounter; i++)
{
library[i].displayBook();
}
}
else if(menuOption == 2)
{
cout << "Enter the Title: ";
cin >> tempt[50];
cout << endl << "Enter the Author's name: " ;
cin >> tempauth[50];
cout << endl << "How many pages does the book have? (just enter a number, e.g. 675, 300): ";
cin >> tempp;
library[bookCounter].setAuthor(tempauth);
library[bookCounter].setTitle(tempt);
library[bookCounter].setPages(tempp);
bookCounter++;
menuOption = 0;
}
else if(menuOption == 3)
{
cout << "Enter a title you would like search for (will return partial matches): ";
cin >> search[50];
for (int i = 0; i < bookCounter; i++)
{
int temp = strcmp(search, library[i].getTitle());
if (temp == 1)
{
library[i].displayBook();
}
}
}
}while(menuOption != 4);
system("pause");
return 0;
}
The problem is caused by the way you are trying to read into the arrays:
cin >> tempt[50];
This tries to read a single character into the character at index 50 of the array tempt, which is outside the bounds of the array (which has valid indices in the range [0,49]).
This means only the first character of the entered title will be consumed from the output. Similarly for author. Hence, only the first two characters which you have entered are actually read. Then, this line will be encountered:
cin >> menuOption;
Here, what is left in the buffer (the remainder of the title) will be read, expecting a number. As this does not match a valid format for a number, you will get an error flag in cin. This will mean that all resulting inputs will also fail, menuOption will never change and your program gets stuck in a loop.
A solution to your problem would be to read into tempt without index. You can also check if a read has failed using if(cin.fail()) which should only trigger if there's been an error. If so, handle it and then call cin.clear() to reset the error flags.
I think that this line cause the problem,
cin >> search[50];
You're accessing out bound of search array.
One error is when you type in the menu option, the 'return' stays in the input buffer. The next read of char[] in your tempt variable, will be skipped.
Type cin.ignore(); after cin >> menuOption;
Also, you should read tempt instead instead of tempt[50].
This
cin >> tempt[50];
accesses a non-existent entry in the array. You probably meant to code
cin >> tempt;
Or, better, use std::string instead of raw char array.

Else statement crashes when i enter a letter for a cin << int value

Alright, I have a question, I veered away from using strings for selection so now I use an integer. When the user enters a number then the game progresses. If they enter a wrong character it SHOULD give the else statement, however if I enter a letter or character the system goes into an endless loop effect then crashes. Is there a way to give the else statement even if the user defines the variable's type.
// action variable;
int c_action:
if (c_action == 1){
// enemy attack and user attack with added effect buffer.
///////////////////////////////////////////////////////
u_attack = userAttack(userAtk, weapons);
enemyHP = enemyHP - u_attack;
cout << " charging at the enemy you do " << u_attack << "damage" << endl;
e_attack = enemyAttack(enemyAtk);
userHP = userHP - e_attack;
cout << "however he lashes back causing you to have " << userHP << "health left " << endl << endl << endl << endl;
//end of ATTACK ACTION
}else{
cout << "invalid actions" << endl;
goto ACTIONS;
}
You haven't shown how you are reading the integer. But in general you want to do something like this:
int answer;
if (cin >> answer)
{
// the user input a valid integer, process it
}
else
{
// the user didn't enter a valid integer
// now you probably want to consume the rest of the input until newline and
// re-prompt the user
}
The problem is that your cin is grabbing the character and then failing, which leaves the character in the input buffer. You need to check whether the cin worked:
if( cin >> k) { ... }
or
cin >>k;
if(!cin.fail()) { ... }
and if it fails, clear the buffer and the fail bit:
cin.clear(); // clears the fail bit
cin.ignore(numeric_limits<streamsize>::max()); // ignore all the characters currently in the stream
EDIT: numeric_limits is found in the limits header file, which you include as per usual:
#include <limits>
Your problem is not with the else-statement, but with your input. If you do something like
cin >> i;
and enter a character, the streams error state is set and any subsequent try to read from the stream will fail unless you reset the error state first.
You should read a string instead and convert the strings contents to integer.