C++ Input validation for strings with loop - c++

I'm trying to make a program in which the user enters in a number and a letter representing what unit of measurement their using (ex inches=i, feet=f, etc) then the letter inputted is used on a series of if statements to see which function to go to convert the number to how many meters it would be. I added an input validation for the units of measure(which are being used as a string variable).My problem is when I input the letter I want to use the program thinks what I entered is invalid even when the input is correct. I removed the input validation and also noticed that the string doesn't even go through any of the if statements. The code is something like this the #include included:
#include <iostream>
#include <string>
using namespace std;
float inTOmeters(float);
float ftTOmeters(float);
float cmTOmeters(float);
float yTOmeters(float);
int main{
float measurement, measurement;
string unit;
cout<<"Enter the number you want to be measured"<<endl;
cin>>measure;
cout<<"Now enter the unit of measurement you want to use"<<endl;
cout<<"i=inches, f=feet, c=centimeters, y=yards, m=meters"<<endl;
cin<<unit;
while(unit !="i"||unit !="m"||unit !="c"||unit !="y"||unit !="f"){
cout<<"Invalid input pick from I, m, c, y, or f"<<endl;
cin>>unit;
}
if(unit=="i"){
measurementm=inTOmeters(measurement);
}
if(unit=="c"){
measurementm=cmTOmeters(measurement);
}
if(unit=="f"){
measurementm=ftTOmeters(measurement);
}
if(unit=="y"){
measurementm=yTOmeters(measurement);
}
else{
measurementm=measurement;
}
cout<<"your measurement will be"<<measurementm<<"in meters."<<endl;
}
I didn't include the functions because I know they work. My question is how do I make it so my loop and if statements function when given the correct input? Also how do I make it so the code accepts capital letters of the correct input?

There are a few problems I see with your program right off the bat. From the code you've provided the variable measure has not been declared and you've declared two variables named measurement.
As for the input, have you thought about handling it with a switch statement? You can use characters for the different cases and write the default case to handle any invalid input.
Lastly, instead of a while loop you could just have your function int main with a return of return main(); which would be a fine way to loop this simple program.

As mentioned, this code has numerous problems and could not possibly compile. Try this:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
float inTOmeters(float);
float ftTOmeters(float);
float cmTOmeters(float);
float yTOmeters(float);
int main()
{
float input, measurement=0.0;
char unit;
cout<<"Enter the number you want to convert:"<<endl;
cin>>input;
cout<<"Now enter the unit of measurement you want to use:"<<endl;
cout<<"i=inches, f=feet, c=centimeters, y=yards, m=meters"<<endl;
while(true){
cin >> unit;
unit = std::toupper(unit);
if(unit=='I'){
measurement=inTOmeters(measurement);
}
else if(unit=='C'){
measurement=cmTOmeters(measurement);
}
else if(unit=='F'){
measurement=ftTOmeters(measurement);
}
else if(unit=='Y'){
measurement=yTOmeters(measurement);
}
else if(unit=='M'){
measurement = input;
}
else if(unit=='X'){
break;
}
else{
cout << "'" << unit << "'" << "is invalid. Choose i, m, c, y, or f." << endl;
continue;
}
cout << input << " is " << measurement << " in meters." << endl;
break;
}
}

A few errors
You never input unit, you need cin >> unit; somewhere.
Logic error, you used 'or' when you should of used 'and'.
while(unit !="i" && unit !="m" && unit !="c" && unit !="y" && unit !="f"){
cout<<"Invalid input pick from I, m, c, y, or f"<<endl;
cin>>unit;
}
I you think about it a minute you'll realise that unit does not equal "i" OR unit does not equal "m" is always true.

Related

Validating Integer input using booleans

In my c++ code, I would like to validate my user input to be an int between 1,10 using a do while loop. I am able to validated for integers outside of the range. However if user inputs a float or a letter, it becomes an infinite loop. My idea is to add a condition in my while loop for if the input is not an integer to keep asking for input.
the CAPITAL letters is where I am having trouble.
#include <iostream>
using namespace std;
int main(){
cout << "Welcome, ";
int steps;
int count=0;
do{
cout << "How many? \n";
cin >> steps;
IF (STEPS IS NOT INTEGER==TRUE){
COUNT=1;
}
if (steps <1)
{
cout << "not enough...\n";
}
if (steps > 10){
cout << "too many steps.\n Please pick a lower number of steps.\n\n";
}
} while (steps < 1|| steps >10 || COUNT==1);
//doing stuff with valid input
return 0;
}
Essentially I am trying to add another condition that just returns a boolean. and if the boolean implies that the input is not valid, then it reassigns count to make sure the do while loops continues until the input is valid.
The problem i am working on asks for a max and min steps, since all of them were having a similar problem i tried to simplify it and forgot some of the edits.
You can check whether the input failed, i.e. the user entered something that could not be read as an int like this:
if (cin.fail()) { // in place of IF (STEPS IS NOT INTEGER==TRUE)
cin.clear();
cin.ignore();
cout << "not an integer, try again\n";
continue;
}
This avoids the need for the COUNT variable.
Also, your while condition doesn't appear to match the checks inside the loop. What happens when step is either 9 or 10? You should be consistent with the checks inside the loop.
You could use the ! operator.
For example:
if ( !(std::cin >> steps) )
{
std::cin.clear();
std::cin.ignore();
std::cout << "Incorrect entry. Try again: ";
}
Also consider not using using namespace std;.

Unable to detect enter key in C++

Now, before this question gets marked for duplicate. I have already gone through most of the questions and their relative answers of C++. These are the links that I have tried and none of them work for me. It maybe because they are using an older version of C++, and I have the latest version of C++. Here are the links that I have tried:
Detecting ENTER key in C++
https://www.sololearn.com/Discuss/1863352/how-can-i-check-that-user-press-enter-key-in-c
http://www.cplusplus.com/forum/beginner/2624/
https://www.dreamincode.net/forums/topic/398680-detect-enter-key/
Now, with the duplicates out of the way. I am making an expression calculator. So, for example if the user input is: 2+2*6*9/9, then the output should be 14.
The code where I suspect that the problem lies is in:
#include <iostream>
#include <vector>
using std::cout;
using std::cin;
using std::string;
using std::vector;
void clear();
void error(string message);
int main() {
cout << "Enter an expression: ";
double l_Value = 0, r_Value = 0, result = 0, count = 0, previous_number;
char op;
while (cin >> l_Value) { // 1+2*3+6-4/2+3
if (!cin) {
error("Invalid operand entered!");
}
else {
bool is_Error = 0; // false
vector<double> numbers;
numbers.push_back(l_Value);
previous_number = l_Value;
while (cin >> op) {
if (op == '\0') {
break;
}
cin >> r_Value;
switch (op)
{
case '+':
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '-':
numbers.push_back((-1 * r_Value));
previous_number = (-1 * r_Value);
break;
case '*':
numbers.pop_back(); // take out the number
r_Value *= previous_number;
numbers.push_back(r_Value);
previous_number = r_Value;
break;
case '/':
if (r_Value == 0) {
error("Sorry, division by zero has occured. Please re-evaluate your expression!\n");
is_Error = 1; // true
break;
}
else {
numbers.pop_back(); // take out the number
previous_number /= r_Value;
numbers.push_back(previous_number);
break;
}
}
}
if (!is_Error) {
for (int i = 0; i < numbers.size(); i++) {
result += numbers[i];
}
cout << result << '\n';
}
numbers.clear();
result = 0;
l_Value = 0;
r_Value = 0;
}
cout << "Enter an expression: ";
}
clear();
return 0;
}
None of the links above seemed to work for me.
When I press the Enter key, it expects me to give another input, and that is not supposed to happen. So when I used cin.get() == 'n' or cin.get() == (int)'\n', it expects for another input. But, when I have an 'x' at the end of the expression, it works perfectly fine. So, I need the "cin" operator to help me detect an Enter character at the end of the expression and then terminate the program.
Here, is a sample run of a program with 'x':
[![running as x-terminator][1]][1]
[1]: https://i.stack.imgur.com/ORPQa.png
When I try the above solution such as "cin.get() == '\n':
Then, I thought that maybe it is reading the null character and so, I tried if (op == '\0'):
For the enter key and null character I had to press Ctrl+Z to terminate the program. Please help!
As, mentioned by user #idclev, I already have a string program that works, but I am trying to avoid using string to calculate any expressions! So, if I could detect an enter key pressed using a character datatype that would be great!
I avoided strings to avoid parsing through the text
That argument is moot. What you can read from cin you can also read from a std::string, no difference whatsoever. You just need to add one step:
#include <iostream>
#include <string>
#include <sstream>
int main( ){
std::string x;
std::cin >> x;
if (x == "") {
std::cout << "user pressed enter (and nothing else)";
} else {
double y;
std::stringstream ss{x};
ss >> y;
std::cout << y;
}
}
This will read one std::string. If user only hit enter then the string will be empty. If the user entered something the else branch will be taken and you can extract the number from the string in the same way you did extract the number from cin (via using a std::stringstream).
If you have more than one number in the input you need to use getline to read the string, because cin will (by default) only read till the next whitespace.
Again...
If I used a string, I would have a tough time in extracting single-digit and two-digit or n-number of digits in a string. The double data type does that for me
You can read single-digit or any number of digits from a stringstream in exactly the same way as you read them from cin.
I already made a program with string in it. I was trying to avoid string to see how much faster would it be without string.
It won't be any faster. Constructing the string and the stringstream is maybe in the order of microseconds. A user entering input is in the order of seconds, maybe milliseconds when they are typing very fast.
Your approach cannot work because hitting enter is not considered as a character. Trying to read a character when there is none in the stream will fail. It will not set the character to \n or \r.
On the outer loop, you are trying to read a double, but you keep pressing enter. There is no input to evaluate, so it keeps trying to read a double. You can get out of it by ending the input stream with ^Z, or you can give it any actual content to read, and it will try to make it into a double (which is what your code explicitly told it to wait for).
Basically, when you press enter, it's ignoring it because
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
Extracts as many characters as possible from the stream and inserts them into the output sequence controlled by the stream buffer object pointed by sb (if any), until either the input sequence is exhausted or the function fails to insert into the object pointed by sb.
Try experimenting with this to see what is happening.
#include <iostream>
#include <vector>
#include <string>
int main() {
double x;
std::cin >> x;
std::cout << "read this value: " << x << std::endl;
// this is what while or if will look at
bool success = !std::cin.fail();
if (success)
std::cout << "success" << std::endl;
else
std::cout << "failure, loop will exit" << std::endl;
return 0;
}
What you should want (in my opinion) is a function that takes the expression as a string, and returns the result, so you can write unit tests, and make sure the function works. You can use this function with any expression that you can put in a string. It doesn't HAVE to be typed in by a user.
If you want the user to type in the experession, it's a lot easier to just use getline() then pass the string to your function. The big problem with using cin on each variable and character is that the user has no idea which datetype is expected right then. Granted, it's not hard to guess with an expression, but you wrote it and debugged it and still didn't know which cin you were failing to get the right datatype to. (this is normal, btw -- been there, which is why I getline and parse separately)

C++ function to check if an input is an integer?

I'm currently writing a C++ program for school that involves taking an input as an amount of change, then telling the user how many quarters, dimes, nickels, and pennies they require to make said change.
However, if the user inputs any sort of character or string the program goes into an infinite loop printing two or three of my messages indefinitely.
Is there a function or some other method I can use to prevent this from happening?
Edit: Here's some of my code that I think represents the issue
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cctype>
#include <sstream>
using namespace std;
int main ()
{
cout << "\nMake Change v0.6.4\n";
cout << "Type 0 at any time to exit the program.\n";
char confirmExit;
int amount;
while (tolower(confirmExit) != 'y')
// allows the user to continue using the program with having to type a.out everytime
// but quit the application at any time with two keystrokes and
// confirmation so as to not accidentally exit the program
{
cout << "\nEnter the amount of change as an integer: ";
// input total cents to be worked with
cin >> amount;
if ((amount)!int)
{
cout << "\nMake sure to type an integer!\n";
}
else if (amount == 0)
{
cout << "Are you sure you want to exit the program(y/n)? ";
cin >> confirmExit;
// confirmation to prevent accidentally exiting out
}
cout << "\n";
return (0);
}
In C++ everything is bits and implicit conversion can takes place to convert string or other forms of data to int value. You can use limits header file in standard library and set the bound for max and min value of input.If you can't get it then comment below. I will post code.
This link might be useful-
Visit http://lolengine.net/blog/2012/02/08/selectively-restrict-implicit-conversions
see the functions defined below:
atoi
strtol

Why "keep_window_open()" doesn't wait for a character to be entered?

I'm new to programming, and I'm trying to learn C++ by myself, and I'm following "Programming principles and practice using C++".
I was trying to do an exercise that, after various other steps, asked me to
" ...change the body of the loop so that it reads just one double each time around. Define two variables to keep track of which is the smallest and which is the largest value you have seen so far. Each time through the loop write out the
value entered. If it’s the smallest so far, write the smallest so far after the number. If it is the largest so far, write the largest so far after the number".
I wrote the following code so far:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() { cout<<"\nType a character to exit: "; char ch; cin>>ch; }
int main()
{
double val1 = 0, smallest = 0, largest = 0;
int flag = 0;
while (cin >>val1) {
if (val1=='|')
break;
else
cout <<val1 <<'\n';
if (flag==0) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n";
}
if (val1<smallest) {
smallest = val1;
cout <<smallest <<" it's the smallest value so far.\n"; }
else if (val1>largest) {
largest = val1;
cout <<largest <<" it's the largest value so far.\n"; }
++flag;
}
keep_window_open();
return 0;
}
My problem is that when I input a character, e.g. 'c', the program ends, although the program should end, hypothetically, only when I enter '|', and I get:
c
Type a character to exit:
Process returned 0 (0x0) execution time : ...
Press any key to continue.
and "keep_window_open()" doesn't wait for a character to be entered. I just can't understand what happens, and why. Does anyone have a clue?
Well, I think the problem is in the way you defined your loop expression.
Neither cin nor its operator ">>" return a true / false value that you can work with. They return an iStream object which could be a dubious translation to true or false via an automated casting that happens behind the curtains. They will however return null when the input cannot be set inside your variable like in the case of trying to put 'c' into a double, and null translates into false.
What I suggest for you is to create a simple while(true) loop and when you get the "|" character from the user(as a string) you break the loop. until then the loop continues. then inside the loop parse your value and work on it according to your logic(minimum / maximum)
Problem
while (cin >>val1) reads input into a double. If you input something that cannot be read as a double like "|" then this will fail and cause your loop to exit.
You then try to read more input while cin is in an error state.
Solution
Call cin.clear() to first clear any error flags and then cin.ignore(1000, '\n') to throw away anything left hanging in the input stream.
inline void keep_window_open()
{
cout << "\nType a character to exit: ";
char ch;
cin.clear();
cin.ignore(1000, '\n');
cin >> ch;
}
Note
if (val1=='|')
break;
This code will never be true because if you try to input the pipe character your while loop will fall through before ever getting to it.

C++: Why Does It Output On Alternative Basis?

Consider the following C++ code: (codeblocks = IDE)
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
int a;
while(cin>>a) {
cout<<"You sir, Just Entered: "<<a<<endl;
if(!(cin>>a)) {
cout<<"Exiting"<<endl;
break;
}
}
}
If I remove the if(!(cin>>a)) { condition and just write cout<<"You sir, Just Entered: "<<a<<endl;, it outputs. Otherwise, currently, it doesn't output on (n+1)th input. See this image:
if(!(cin>>a)) { is catching your next input (e.g. 2, 4, 6 ,8).
Then, it doesn't go inside the if statement because of the negation !
It doesn't display your second input because you do not print a after your second cin
You're catching input twice per iteration : once in the while's conditions, and a second time in the if's condition. Thus, only one in two inputs get printed. That's because even if the if's condition fails, it has already read by then.
Your while loop already does the check : it won't iterate if the user enters a non-number. Your fixed code is simply :
int main() {
int a;
while(cin>>a) {
cout<<"You sir, Just Entered: "<<a<<endl;
}
cout<<"Exiting"<<endl;
}
if you want to check for non-integer input this will do.
int a;
while(cin >> a)
{
cout << "Sir you entered: " << a <<endl;
}
cout << "Exiting"
<<endl;
the checking is done automatically in the while loop because the input yields true if it is valid (integer in your case) this allows further inputs. if the input isn't valid, the program leaves the loop and the exiting message is displayed.