Validate User Input C++

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 3339 Views - Last Post: 18 June 2011 - 03:09 PM Rate Topic: -----

#1 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Validate User Input C++

Posted 18 June 2011 - 05:28 AM

Hi, I'm trying to validate user input to make sure that it is of the type of variable I'm storing it in.

double x = 0.0;
cout << "Enter a value";
cin >> x;
x = x * 5;
cout << x << endl;



If I input anything other than a numeric value my program doesn't work. I am new to C++ and thought this would be a very simple problem to solve but I have tried to find a solution but couldn't understand most of them.

Thanks for your help.

This post has been edited by Johnny64: 18 June 2011 - 05:29 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Validate User Input C++

#2 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 05:31 AM

Try this:
while (1) {
    if (cin >> x) {
        x = x * 5;
        break;
    }
    cin.clear();
    cin.ignore();
}
cin >> x ends up as false if the user enters the wrong value, so we loop until it's true (the user enters the right value). You also need to clear and ignore the wrong input.
Was This Post Helpful? 0
  • +
  • -

#3 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Re: Validate User Input C++

Posted 18 June 2011 - 05:37 AM

Ok sorry I'm new and I don't understand how I would apply that to my program here:
#include <iostream>
#include <cmath>

using std::cin;
using std::cout;
using std::endl;
using std::wcout;
using std::wcin;

int main ()

{
	double x = 0.0;
	double x1 = 0.0;
	double x2 = 0.0;
	double a = 0.0;
	double b = 0.0;
	double c = 0.0;
	double t1 = 0.0;
	double t2 = 0.0;
	double triangle = 0.0;
	double t3 = 0.0;
	double t4 = 0.0;
	double t5 = 0.0;
	double t6 = 0.0;

	cout << "The program will ask you for the values a, b, and c of your quadratic equation.\n" ;


 for (int i = 2; i >= 1; ++i)
 {

		cin.clear();

		while (cout << "Enter the 'a' value: ",! (cin >> a))
		{
			cin.clear();
			cin.ignore(1000,'\n'); 
		}
		cin.clear();
		while (cout << "Enter the 'b' value: ",! (cin >> B)/>)
		{
			cin.clear();
			cin.ignore(1000,'\n'); 
		}
		cin.clear();

		while (cout << "Enter the 'c' value: ",! (cin >> c))
		{
			cin.clear(); 
			cin.ignore(1000,'\n');
		}
		cin.clear();
	

		t1 = b*b;
		t2 = 4*a*c;
		triangle = t1 - t2;
		t3 = -1*b;
		t4 = sqrt(triangle);
		t6 = t4;
		t5 = 2*a;

		if (triangle >= 0.0)
		{
		x1 = (t3 + t6) / t5 ;
		x2 = (t3 - t6) / t5 ;
		cout << "The two values of 'x' are: " << x1 << " and: " << x2 << endl;
		cout << endl;
		}
		else
		{
		cout << "There are no solutions for 'x' in your equation. \n";
		cout << endl;
		}
		cin.clear();
		char response;
		cout << "Would you like to solve another equation? \nPress N for NO and any other key for YES: ";
		while (! (cin >> response))
		{
			cin.clear(); 
			cin.ignore(10000,'\n'); 
			cout << "Please press one key only: ";
		}
		cin.clear();
		if (!((response == 'N') || (response == 'n')))
		{
		 cout << endl;
		 cin.clear();
		 continue;
		}
		else
		{
			cout << "Thank you for using Quadratic Solver";
			break;
		}

	}
	return (0);

}

I would like to make it valid for the first 3 inputs, but whenever I enter "21321edasd" into the "Enter a value" then it will come up with "Enter b value: Enter b value:". I don't know how to make it not appear twice.

Thanks for your help.

This post has been edited by Johnny64: 18 June 2011 - 05:38 AM

Was This Post Helpful? 0
  • +
  • -

#4 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 05:42 AM

Move the cout to the beginning of the while loop, rather than the loop clause, and cout enter a value to before the loop:
cout << "enter a value: ";
while(!(cin >> a)) {
    cout << "enter a value: ";
    cin.clear();
    cin.ignore((unsigned)-1, '\n');
}
That should work.
Was This Post Helpful? 0
  • +
  • -

#5 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Re: Validate User Input C++

Posted 18 June 2011 - 05:47 AM

Ok so I tried that, this is what my code looks like:
#include <iostream>
#include <cmath>

using std::cin;
using std::cout;
using std::endl;
using std::wcout;
using std::wcin;

int main ()

{
	double x = 0.0;
	double x1 = 0.0;
	double x2 = 0.0;
	double a = 0.0;
	double b = 0.0;
	double c = 0.0;
	double t1 = 0.0;
	double t2 = 0.0;
	double triangle = 0.0;
	double t3 = 0.0;
	double t4 = 0.0;
	double t5 = 0.0;
	double t6 = 0.0;

	cout << "The program will ask you for the values a, b, and c of your quadratic equation.\n" ;


 for (int i = 2; i >= 1; ++i)
 {

		cin.clear();

		cout << "enter a value: ";
		while(!(cin >> a))
		{
		cout << "enter a value: ";
		cin.clear();
		cin.ignore((unsigned)-1, '\n');
		}

		
		cout << "enter a value: ";
		while(!(cin >> B)/>)
		{
		cout << "enter b value: ";
		cin.clear();
		cin.ignore((unsigned)-1, '\n');
		}

		
		cout << "enter a value: ";
		while(!(cin >> c))
		{
		cout << "enter c value: ";
		cin.clear();
		cin.ignore((unsigned)-1, '\n');
		}

		
		cin.clear();
	

		t1 = b*b;
		t2 = 4*a*c;
		triangle = t1 - t2;
		t3 = -1*b;
		t4 = sqrt(triangle);
		t6 = t4;
		t5 = 2*a;

		if (triangle >= 0.0)
		{
		x1 = (t3 + t6) / t5 ;
		x2 = (t3 - t6) / t5 ;
		cout << "The two values of 'x' are: " << x1 << " and: " << x2 << endl;
		cout << endl;
		}
		else
		{
		cout << "There are no solutions for 'x' in your equation. \n";
		cout << endl;
		}
		cin.clear();
		char response;
		cout << "Would you like to solve another equation? \nPress N for NO and any other key for YES: ";
		while (! (cin >> response))
		{
			cin.clear(); 
			cin.ignore(10000,'\n'); 
			cout << "Please press one key only: ";
		}
		cin.clear();
		if (!((response == 'N') || (response == 'n')))
		{
		 cout << endl;
		 cin.clear();
		 continue;
		}
		else
		{
			cout << "Thank you for using Quadratic Solver";
			break;
		}

	}
	return (0);

}


and this is the output:
The program will ask you for the values a, b, and c of your quadratic equation.
enter a value: 213assda
enter a value: enter b value:



So unfortunately it is not working perfectly. Could you please suggest some other things I could do to fix it?

Thanks
Was This Post Helpful? 0
  • +
  • -

#6 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 05:53 AM

Close, but no cigar.
		cout << "enter a value: ";
		while(!(cin >> B)/>)
		{
		cout << "enter b value: ";
		cin.clear();
		cin.ignore((unsigned)-1, '\n');
		}
You cout "enter a value" here where you mean "enter b value" (the same occurs later for c). Also, you've used capital B -- variables are case sensitive, so B != b. Fix those and it works 100% fine (I tested it).

Note for future reference: (unsigned)-1 is a shortcut for the highest number available.

This post has been edited by PlasticineGuy: 18 June 2011 - 05:53 AM

Was This Post Helpful? 0
  • +
  • -

#7 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Re: Validate User Input C++

Posted 18 June 2011 - 05:59 AM

Ok so I changed it again, and now the output is this:
The program will ask you for the values a, b, and c of your quadratic equation.
enter a value: 213assda
enter b value: enter b value:



So like the double thing still appears if you enter an input that consists of both numerical and alphabetical values. Do you know how to fix it?

Thanks again
Was This Post Helpful? 0
  • +
  • -

#8 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 06:00 AM

Can you post your full code again? Also, what compiler are you using? On my compiler I get the expected output.

EDIT: After doing some debugging I can confirm that the number holds the correct value of 213. This means that we can fix it by also including this after each while loop:
cin.clear();
cin.ignore((unsigned)-1, '\n');

So the total should be:
		cout << "enter a value: ";
		while(!(cin >> a))
		{
		cout << "enter a value: ";
		cin.clear();
		cin.ignore((unsigned)-1, '\n');
		}
		cin.clear();
		cin.ignore((unsigned)-1, '\n');

This post has been edited by PlasticineGuy: 18 June 2011 - 06:02 AM

Was This Post Helpful? 0
  • +
  • -

#9 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Re: Validate User Input C++

Posted 18 June 2011 - 06:06 AM

Oh my god.... It works. Thank you so much. If it's not too much of a hassle for you, could you please explain to me how adding another:
cin.clear();
cin.ignore((unsigned)-1, '\n');

Fixes the repeating problem?

I'm learning C++ and would love to understand how this works.

Thanks
Was This Post Helpful? 0
  • +
  • -

#10 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 06:09 AM

OK, sure.
Basically cin.clear(); clears any input waiting to be read. Reading from cin again without doing this (cin >> a) will just read any extra input that wasn't read because it was an error. cin.ignore((unsigned)-1, '\n') is a little more complicated; it ignores any input that was read but rejected (for example attempting to read a string into an int) up until it hits '\n', the newline character (or until it reaches about 4 million characters, but that's another issue).

These lines makes sure the next input and output will work correctly. Because we *know* the 213 was read correctly (the debugger told us), that means the "assda" part was waiting to be read or cleared. This causes all sorts of interesting bugs when you next try to use cin or cout without clearing it with clear and ignore.
You might find this post insightful: http://www.dreaminco...6&#entry1365836

Out of curiousity what inputs are you using to check the solver portion is correct?

This post has been edited by PlasticineGuy: 18 June 2011 - 06:12 AM

Was This Post Helpful? 0
  • +
  • -

#11 Johnny64  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 18-June 11

Re: Validate User Input C++

Posted 18 June 2011 - 06:13 AM

Thank you, you have been extremely helpful. I'm going to sleep now, have a nice day.

Oh for the solver portion I put any numerical input and if it is a valid quadratic equation it will output the correct values, and if it is not it will tell you there are no solutions, I tested this with online quadratic solvers and they have the same results so yeah.

This post has been edited by Johnny64: 18 June 2011 - 06:20 AM

Was This Post Helpful? 1
  • +
  • -

#12 jimblumberg  Icon User is offline

  • member icon


Reputation: 4096
  • View blog
  • Posts: 12,673
  • Joined: 25-December 09

Re: Validate User Input C++

Posted 18 June 2011 - 06:37 AM

Quote

Note for future reference: (unsigned)-1 is a shortcut for the highest number available.


In my opinion it would be better to use:
cin.ignore(numeric_limits<streamsize>::max(), '\n');
This will insure that you are using the correct data type and makes your intent clear.

And remember that rollover behavior in a signed integer is undefined.

Jim
Was This Post Helpful? 2
  • +
  • -

#13 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 06:47 AM

Thanks for the extra advice; however for that to work you need to #include <limits> and I didn't want to confuse the OP.
Was This Post Helpful? 0
  • +
  • -

#14 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Validate User Input C++

Posted 18 June 2011 - 07:00 AM

View PostPlasticineGuy, on 18 June 2011 - 09:09 AM, said:

(for example attempting to read a string into an int) up until it hits '\n', the newline character (or until it reaches about 4 million characters, but that's another issue).


Technically speaking this is not true and demonstrates one of the reason you SHOULD use this:

cin.ignore(numeric_limits<streamsize>::max(), '\n');

instead of (unsigned)-1 (which would be a -1 cast to an unsigned int and streamsize might be a 64bit int for all you know).

cin.ignore(numeric_limits<streamsize>::max(), '\n');

this does not ignore numeric_limits<streamsize>::max() chars... it will ignore EVERYTHING until the next '\n' - so if you need to ignore 80billion chars this will do that. The maximum number of chars you can ignore specifically is: numeric_limits<streamsize>::max() - 1 -- but the max value of streamsize is considered a special case and by the standard all chars are ignored until the first '\n'.

So if you are reading from some char generator that never produces a '\n' you could be stuck in an infinite loop here.

I was going to quote MSDN but it would seem they have a slight bug in their documentation. They say:

Quote

The unformatted input function extracts up to _Count elements and discards them. If _Count equals numeric_limits<int>::max, however, it is taken as arbitrarily large.


Although I am not 100% sure about their implementation I would bet that it is at least numeric_limits<unsigned int>::max
Was This Post Helpful? 2
  • +
  • -

#15 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Re: Validate User Input C++

Posted 18 June 2011 - 07:17 AM

Thanks for the in-depth advice -- I had no idea this was the case!
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2