How can I make cpp to distinguish input(cin)? - c++

I'm trying to solve the question in programming : principles and practice using c++
Q. make a code that reads two int values and prints them. Make '|' input stop the program.
use while loop
I have no idea to distinguish whether the input is int or '|'

This question:
make a code that reads two int values and prints them. Make '|' input stop the program. use while loop
indicates that author doesn't know c++ well or task was stated for different language. It is also possible you didn't copy paste whole description of task.
When next character to read is | trying reading integer value will fail, so no special check has to be done.
So just read pairs of int values until error occurs. Special check for | is obsolete.
int a, b;
while (std::cin >> a >> b)
std::cout << (a + b) << '\n';
https://godbolt.org/z/P95z4a

Here is a solution.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string value1, value2;
while(1) //infinity loop
{
cout << "Enter value one" << endl;
cin >> value1;
cout << "Enter value two" << endl;
cin >> value2;
if(value1 == "|" || value2 == "|") // the || is a logical OR. If v1 oder v2 is | break the while loop
{
break;
}
cout << value1 << " + " << value2 << " = " << (std::stoi(value1)+std::stoi(value2)) << endl; //std::stoi makes a string a number, so it means string to int
}
return 0;
}
Compile it with the c++11 flag for stdoi:
g++ -std=c++11 example.cpp -o example
PS: don't ask stackoverflow to do your homework for you. Try to learn for yourself. You will need it in the job and your colleagues will depend on you.

You can pour your input into string type variable cin >> tmp_str. Then check if it is euqal to '|', if not you can convert it to integer using stoi or any alternatives.

Try reading the user input as a string and checking whether it's equal to |:
#include <iostream>
#include <string>
int main() {
std::string input;
while (input != "|") {
std::getline(std::cin, input);
// read int values here
}
}

Related

What do you do in C++ if you ask for an integer and the user inputs "b"?

I'm new to statically typed C++. In JavaScript, I could just check the data type first, but that seems to be very complicated, and the answers all seem to imply that you aren't "getting" the language.
here's the code I was testing out rand() with, where I came upon the issue of converting strings to integers:
int main(){
std::string input;
cout <<endl<< "What to do?"<<endl;
cin >> input;
if (input == "rand")
{
cout << "what is the max?" << endl;
cin >> input;
int number;
if (stoi(input) > 1) {
number = stoi(input);
}
else {
number = 10;
cout << "using 10"<<endl;
}
cout << rand() % stoi(input);
return main();
}
}
so in Javascript, I would just check the type of input or result, but what do people do in C++?
Not allowed to say thank you in the comments so I'm saying thank you here!
Well, let's try out what happens: https://godbolt.org/z/1zahbW
As you can see, std::stoi throws an exception if you pass it invalid input or its input is out of range.
You should, however, be aware that std::cin >> some_string; is somewhat non-obvious in that it reads in the first "word", not a line or anything like that, and that std::stoi does the same thing (again).
One way to perform the check, could be like this:
#include <string>
#include <iostream>
int main(){
std::cout << "Please give me a number: " << std::flush;
std::string input;
std::getline(std::cin, input);
try {
auto value = std::stoi(input);
std::cout << "Thanks for the " << value << " (but the string was \"" << input << "\")\n";
} catch(std::invalid_argument const&) {
std::cout << "The provided value is not an integer\n";
} catch(std::out_of_range const&) {
std::cout << "The provided value is out of range\n";
}
}
https://godbolt.org/z/rKrv8G
Note that this will parse " 42 xyz" as 42. If that is a problem for your use case, you may wish to use std::strtoi directly, or to check if your input is valid before parsing (e.g., using a regex)
Regarding to the documentation of std::stoi it throws an std::invalid_argument.
What you could do is to place your std::stoi call inside a try and then catch the std::invalid_argument, but personally i wouldn't do that.
Instead, it is (most likely) a lot better to check if the first character of your input is an int, because if it is one, it can simply be parsed by std::stoi.
You can do that by e.g. doing the following:
int max = 0;
std::string input;
std::cin >> input;
if(std::isdigit(input[0]))
max = std::stoi(input);
EDIT: Please note that this would not respect the case of a too big number, to handle that case you would need an additional check.

Isspace Character Function

I'm new to this and currently studying C++. I'm currently learning about Character Functions in cctype(ctype). I'm having trouble understanding why the isspace(a_character) is not returning my cout message -- the problem is it wont even accept my Char user input. Any help or steering to the right direction would be greatly appreciated. I can achieve the response I want if I assign the Char value of: ' ' , however, it defeats the purpose. I've copied a portion of my code. To my understanding, there's no exact symbol for Whitespace? if so, is it possible to even enter a whitespace as an input? I've tried entering : ' ' however, have not been successful. Again, I'd greatly appreciate it.
#include <iostream>
#include <cctype>
#include <ctype.h>
using namespace std;
int main()
{
char c ;
char ans = 'y' || 'Y';
do {
cout << "Enter a character \n";
cin >> c;
if (isspace (c)) //Having trouble get this to actually produce a value
{
cout << "Your character " << c << "is a whitespace";
}
if (ispunct(c))
{
cout << c << " is a punctuation character\n";
}
cout << "Would you like to enter another value? \n";
cin >> ans;
} while (ans == 'Y' || ans == 'y');
return 0;
}
>> is a formatted extractor. Formatted extractors, by default, extract and discard all whitespace characters before they actually read anything. That's useful behavior, but not when you are trying to read a whitespace character.
Either use unformatted input (get()) or the noskipws manipulator. Note that your later reading of ans in all likelihood depends on skipping whitespace to work correctly, so you'd probably want to restore the whitespace-skipping behavior with skipws after you read c if you choose the second option.

Converting char to int when asked to enter an integer and checked with isdigit

So recently, I came across using isdigit as a way to check to see if an entered value for an int is actually an integer, rather than a string or a char.
However, when I wrote a short program to play around with that, the program failed to execute from that point on.
EDIT: I also in the program wanted to take the invalid data and convert it to a different data type.
Here is the code:
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
int enterCFN;
char revisit;
int review(0);
cout << "Enter a digit: ";
cin >> enterCFN;
bool y = isdigit(enterCFN);
if (y == false)
{
// This is the data conversion section
revisit = enterCFN;
revisit = review;
cout << review << "\n";
}
else
{
cout << enterCFN << "\n";
}
return 0;
}
Is there anyone who can correct my error and show me what I'm doing wrong?
enterCFN is an int. It stores a number. isdigit() checks if a character represents a number. These are not the same thing: for example 32 is a number but char(32) means ' ' (space).
What you want instead is this:
if (cin >> enterCFN)
That will take the input from the user and check if it is valid all at once. No need for isdigit().
isdigit() checks if a given character is one of 0-9
For validating integer do something like following:
std::cout << "Enter a digit: ";
std::cin >> enterCFN ;
while (1)
{ if ( std::cin >> enterCFN )
{
// good input
break ;
}
else
{
std::cout << "Enter a digit: ";
// clear stream flags set due to bad input
std::cin.clear();
// get rid of the bad input.
// ignore the rest of the line
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}

Unexpected stringstream behavior

Consider the following code:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream ss;
ss << string("12");
int h;
ss >> h;
cout << h << endl;
ss.str(string("")); // clear the content of ss
ss << string("30");
int m;
ss >> m;
cout << m << endl;
return 0;
}
Running the above code yields some random output:
12
0
At some other times, the following output is observed:
12
4
I expected the output to be simply:
12
30
Why did I get the unexpected results?
Also, what should be the best way to parse a string s to int i without necessary C++11 support? Should it be int i = atoi(s.c_str())?
When you extract 12 from the stream, you reach the end of it, which puts it in a bad state. Any further extractions will fail. You need to call ss.clear() around the time you clear its contents.
If you had checked the success of your extractions, you would have avoided this problem. I generally expect to see any extraction from a stream as some kind of condition.
And yes, using string streams to parse strings as integers is a perfectly reasonable way to do it pre-C++11. I would prefer it over using atoi. For anybody who wants to know the C++11 way, use std::stoi.
For those who're here with something similar to the above but not exactly, I found that when you've got a stream in a scenario where you need to re-use it (like in a while loop), the easiest way to avoid head-aches (in addition to ss.clear) is to create a new stream each time. For example:
int GetInteger(){
cout << "Enter an int: " << endl;
string userInput;
while (true){
stringstream ss;
getline(cin,userInput);
ss << userInput;
//Making sure that an int was passed
int result;
if (ss >> result){
//Making sure that there is no extra stuff after
string extra;
if (ss >> extra){
cout << "Unexpected stuff at end of input: " << extra << endl;
} else{
return result;
}
} else {
cout << "Number you entered is not an INT. Please enter an integer" << endl;
}
cout << "Retry: " << endl;
// ss.clear();
}
}
So every time the user enters an invalid input, at the start of the while loop, I create a new stringstream object. While researching my function's undefined behavior, I found this question that has a similar example.

Testing for an integer in c++

I'm trying to write a c++ program that tests each input integer, and stops if the input is invalid.
Here is my code, without the testing part:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int i;
do
{
cout << "\nPlease enter an integer: ";
cin >> i;
cout << endl << i << endl;
} while(i != 0);
system("Pause");
return 0;
}
How can I test the input for validity?
The easiest is to use std::getline to read a whole line of input into a std::string, and then test whether that string is a valid integer specification.
It's also possible to do this by testing the failure state of cin, and clearing it, but that way lies an assortment of complications that you don't want.
In order to test the string you can use a high level std::istringstream (just read from it and test its failure state after) or, more efficient but a little more complicated, strtol from the C library (the latter is what a C++ stream uses internally).
You need to test whether a string is an integer without crashing.
You can do this with strtol(). It converts the string to an integer, and reports on the first character that is not a legal char for a number. No invalid characters means the entire string was an integer.
There is a good description and example of how to use it here:
http://www.tutorialspoint.com/c_standard_library/c_function_strtol.htm
#include <iostream>
#include <stdlib.h>
using namespace std;
int main()
{
int i;
do
{
cout << "\nPlease enter an integer: ";
while(!(cin >> i))
{
cin.clear();
cin.ignore();
cout << "\nInput was invalid, please re-enter: ";
}
cout << endl << "The integer is: " << i << endl;
} while(i != 0);
system("Pause");
return 0;
}