How to stop input in this code- a code to input an 1D array with unknown size - c++

I try to do this but i don't know how to stop input. I build a code with input an array with integer element, when input element not integer, it will ignore. So i can't stop it.
do {
if(std::cin >> val) {
if(val == 0) break;
vec.push_back(val);
} else {
std::cin.clear();
std::cin.ignore(1,'\n');
}
} while(true);
I try to enter ctrl + x,z,d but it don't work.

You can decide to stop input on end of file. The condition is raised on actual end of file when you read from a true file, or but using Ctrl Z or F6 on Windows or Ctrl D on Linux. You just have to test for it before ignoring any offending input:
do {
if(std::cin >> val) {
if(val == 0) break;
vec.push_back(val);
} else if (std::cin.eof()) {
break; // exit loop on eof
} else {
std::cin.clear(); // ignore any offending input up to end of line
std::cin.ignore(1,'\n');
}
} while(true);

Related

How to ignore wrong cin input in C++?

This is code for a 4x4 tic-tac-toe game. I am new to programming. I don't know how to ignore wrong input from the user. I tried searching Google, I found cin.clear() and cin.ignore(). They did work a little bit, but not fully working. For example, if the user enters 11111111 4 o as input, the program exits instead of ignoring this. How to ignore this input?
And what are cin.clear() and cin.ignore() doing?
char game[4][4];
int r, c;
char ans;
cin >> r >> c >> ans;
--r, --c;
if (!check_ok(r, c, ans)){
cout << "try again: select available ones only!!!\n";
--count;//count checks for 16 turns through while loop
}else{
game[r][c] = ans;
++count1;
}
bool Game::check_ok(int a, int b, char an) {
if (game[a][b] == ' ' && a < 4 && b < 4 && ((count1 % 2 == 0 && an == 'x') || (count1 % 2 != 0 && an == 'o'))){
game[a][b] = an;
return true;
}
else{
cin.clear();
cin.ignore();
return false;
}
}
OK. User input is hard.
Interactive user input is line based.
User inputs some values and then hits return. This flushes the stream and unblocks the readers to get the value from the stream. So you should design your input code to be line based.
The first question seems to be is all the input on one line or do they input the values with a return between each? You can determine this with some outut to the user then follow the rules defined by your instructions.
So lets do a line based input example:
do {
// Your instructions can be better.
std::cout << "Input: Row Col Answer <enter>\n";
// Read the user input. 1 Line of text.
std::string line;
std::getline(std::cin, line);
// convert user input into a seprate stream
// See if we can correctly parse it.
std::stringstream linestream(std::move(line));
// Notice we check if the read worked.
// and that the check_ok() returns true.
// No point in call check_ok() if the read failed.
if (linestream >> r >> c >> ans && check_ok(r, c, ans)) {
break;
}
std::cout << "Invalid Input. Please try again\n";
}
while(true);
i think instead of ignoring the wrong input you should limit the users input into the ideal inputs only. maybe an if statement could help
if(input != ideal_input)
{
cout>>"invalid input";
}
else
{
//progress in the game
}

wrong input will exit the program c++

So I have started to learn c++ and I have wrote this simple program , when a user inputs wrong number it gives an option to try again however when a user inputs any characters it gives the option to try again and directly exits the program why is that happening ?
`
#include<unistd.h>
#include<stdio.h>
int main(){
int a;
char b ,c;
start:
printf("INPUT ONLY NUMBER 1 : ");
scanf(" %d", &a);
if(a==1)
{
printf( " you entered correctly \n");
printf("do you want to try again? <Y> <N> \n");
scanf(" %c", &c);
if(c=='Y' ||c=='y')
{
goto start;
}
}
else {
sleep (1);
printf("wrong number , do you want to try again? <Y> <N> \n");
scanf(" %c" , &b);
}
if (b=='Y'||b=='y')
{
sleep(1);
goto start;
}
else
if(b=='n'||b=='N')
{
sleep(1);
printf("thank you and goodbye");
exit (1);
}
}
`
scanf(" %d")
I bet your problem comes from that space before the %d. Try scanf("%d"). Same later: scanf("%c") instead of scanf(" %c ").
Anyway, your code is VERY dirty. And this looks like C, not C++.
Not trying to be a maniac here, but you should indent properly and AVOID the goto BY ALL MEANS. Your program structure is simple and a while loop will do the trick for you. You should also avoid to explicitly call exit(1). exit is mostly used to provoke premature termination. In your case, your program reaches its end normally, and you should exit with your main function's return 0.
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h> //Reauired to use boolean type in C
int main()
{
bool stop = false; //boolean type only has two states: true and false. Very useful for loops!
while(!stop) //Read as "While we don't need to stop, execute the loop's contents
{ //Much easier to read!
printf("INPUT ONLY NUMBER 1 : ");
scanf("%d", &a);
if(a == 1)
{
printf("you entered correctly \n");
printf("do you want to try again? <Y> <N>\n");
scanf("%c", &c);
if(c == 'N' || c == 'n')
{ //We only need to tell the loop when to stop
stop = true; //by setting stop to true
} //The loop's default behavior is to loop execution of its content
}
else
{
sleep(1);
printf("wrong number , do you want to try again? <Y> <N> \n");
scanf("%c" , &b);
if(b=='n'|| b=='N')
{
stop = true; //Same as above
}
sleep(1);
}
}
printf("thank you and goodbye");
return 0;
}
There is something left behind from your scanf, which sometimes you can clean that up flushing it, but in your code seems not to work.
Having a look at that issue this comes across:
http://c-faq.com/stdio/stdinflush2.html
Which basically tells you that if your approach does not work, then you should change it.
Hope this help, you also asked about while in one of your questions there, so:
#include <iostream>
int main(){
char input;
char try_again;
do {
std::cout << "INPUT ONLY NUMBER:";
std::cin >> input;
// http://en.cppreference.com/w/cpp/string/byte/isdigit
// does not return a bool, you can check that >0
if (std::isdigit(input)) {
// do what you want.
std::cout << "digit\n";
continue;
} else {
// you can as for more imput like:
std::cout << "Not a number, try again?(y/Y):";
std::cin >> try_again;
std::tolower(try_again);
if (try_again == 'y') {
continue; // will start the loop again.
} else {
break; // it will exit the loop.
}
}
} while(true);
return 0;
}

How do I allow different amounts of input in c++

Assume all variables exist (didnt bother declaring them all here)
if(input=='R') goto restart;
if(input=='X') exit(0);
if(input=='D') moveRight(edgeLength, board, score);
if(input=='S') moveDown(edgeLength,board, arrSize);
if(input=='A') moveLeft(edgeLength,board, arrSize);
if(input=='W') moveUp(edgeLength,arrSize,board);
if(input=='P')
{
cin>> number>>position;
board[position]=number;
}
This input is put into a loop, so the user is asked for input so long as this game is in play.
My goal is to allow for input such as
p 3 50
to place the number 50 at index position 3.
With my current code, I have to type 'p' press enter, then the next two numbers.
However, id like the program to detect 'p 3 50' (enter) in one go, as 'D'(enter) signifies moveRight.
I hope I'm being clear in my question.
cin >> input >> number >> position;
if(input=='R') goto restart;
else if(input=='X') exit(0);
else if(input=='D') moveRight(edgeLength, board, score);
else if(input=='S') moveDown(edgeLength,board, arrSize);
else if(input=='A') moveLeft(edgeLength,board, arrSize);
else if(input=='W') moveUp(edgeLength,arrSize,board);
else
{
//whatever statements for last condition;
}
If you want to capture all three input at once, you can get the input first, then execute the respective actions according to the received inputs.
Added: Using if or else-if depends on situation. From what I see here in your code snippet, else-if is better than if because you can only have one input type everytime. Once matching character is found, (example 'D'), it will stop reading the codes below (which should be the way as it is unnecessary to check the rest of the conditions whether input is 'S' or 'A' or 'W' anymore since you already got the input). Makes your code fun slightly faster too, by preventing unnecessary checking on the conditions.
Proof Of Concept:
//Example
void fncOne()
{
cout << "This is function one" << endl;
}
void fncTwo()
{
cout << "This is function two" << endl;
}
int main()
{
char input;
int number, position;
cin >> input >> number >> position;
if (input == 'A') fncOne();
else if (input == 'B') fncTwo();
}
Input: A 3 5
Output: This is function one
Well, first you're going to want to get user input as a string rather than individual types.
std::string input;
std::cin >> input;
then you'll want to parse that string based on how many words for key words/characters.
e.g.
std::vector<std::string> words;
std::stringstream stream(input); std::string temp;
while(stream >> temp)
words.push_back(temp);
if(words.size() == 3){
if(words[0][0] = 'p'){
int number = std::stoi(words[1]);
int position = std::stoi(words[2]);
board[position] = number;
}
else
... get input again ...
}
else if(words.size() > 1){
... get input again ...
}
else{
char c = words[0][0];
if(c == 'w')
moveUp(edgeLength,arrSize,board);
else if(c == 's')
moveDown(edgeLength,board, arrSize);
else if(c == 'a')
moveLeft(edgeLength,board, arrSize);
else if(c == 'd')
moveRight(edgeLength, board, score);
else if(c == 'x')
exit(0);
else if(c == 'r')
goto restart;
else
... get input again ...
}
Of course this is only one way if you want to type one string then press enter only once.

Errors not printing correctly..Is this logic flow correct? c++

Example user input:
PA1 9 //correct
PJ1 9 //wrong, error printed "Invalid row" because it is not between A and I
PA11 9 //wrong, error printer "Invalid column" because it is not between 1 and 9.
The problem I am having is that it should clear the remaining input and then ask for the user to enter the "move" again, and it is not.
Where did I go wrong? I've been at it for a while and still got no progress..
void clearInput()
{
cin.clear();
}
bool getCoords(int & x, int & y)
{
char row;
while(true){
cin>>row>>y;
row=toupper(row);
if(/*(id=='P' || id=='p' || id=='D' || id=='d') && */row>='A' && row<='I' && isalpha(row) && y>=1 && y<=9){
x=row-'A';
y=y-1;
return true;
}
else if(!(y>=1 && y<=9)){
cout<<"Invalid column\n"<< endl << endl;
cout<<y;
clearInput();
cout<<y;
//return false;
}
else{
cout<<"Invalid row\n"<< endl << endl;
clearInput();
//cout<<x<<y;
//return false;
}
}
}
cin's clear member function doesn't clear the remaining input, it resets the error flags on the stream (which could get set e.g. because you tried to read an integer but there were non-digit characters in the input). I guess you really want to discard the input up to the next newline; one way to do this would be to call cin.ignore with '\n' as the delimiter.
Another thing that could be an issue (but might just be code left out in the question ;)) is that the while(true) loop that you've written to repeatedly ask for input until there's no error doesn't contain the board-redrawing logic you talk about in your comment. So you won't see this until the getCoords function finds error-free input and returns.

User Input of Integers - Error Handling

I'm having some trouble with certain input areas of my program. There are a few parts where the user inputs a specific integer. Even if they enter the wrong one that's all fine and dandy, but I noticed if they enter anything not of integer type like 'm' then it will loop the error message repeatedly.
I have a couple functions that have integer input in them. Here's one for an example.
void Room::move(vector<Room>& v, int exone, int extwo, int exthree, int current)
{
v[current].is_occupied = false;
int room_choice;
cout << "\nEnter room to move to: ";
while(true)
{
cin >> room_choice;
if(room_choice == exone || room_choice == extwo || room_choice == exthree)
{
v[room_choice].is_occupied = true;
break;
}
else cout << "Incorrect entry. Try again: ";
}
}
There is still a problem in your "solved" code. You should check for fail() before checking the values. (And obviously, there is the problem of eof() and IO failure as opposed to format problems).
Idiomatic reading is
if (cin >> choice) {
// read succeeded
} else if (cin.bad()) {
// IO error
} else if (cin.eof()) {
// EOF reached (perhaps combined with a format problem)
} else {
// format problem
}
You can use cin.good() or cin.fail() to determine whether cin could successfully deal with the input value provided. You can then use cin.clear(), if necessary, to clear the error state before continuing processing.
For a even simpler way, you can use ! operator like this:
if ( !(cin >> room_choice) )
{
cin.clear();
cin.ignore();
cout << "Incorrect entry. Try again: ";
}