Beginner's cin validation

I am wondering if someone could write a very simple example of an entry validation function. I am trying to understand how to do it, but I am working with a currently limited understanding. I know you are supposed to read cin as a string. From there I want to check to see if the entry is zero, positive, negative, a whole number, a decimal, or none of these. The code I have pasted shows the kind of things I have been experimenting with, though I am not feeling too confident using these things since I haven't been able to figure this out. I realize that beginner's code might not actually be the best way to do things, but what I really want is just somewhere to start where I can begin to understand what is happening.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <string>
#include <sstream>

void entryValidation();

int main()
{
	// This is where I use functions to test different things.
	entryValidation();	
}

void entryValidation()
{
	std::string userInput;
	double doub01 = 0.0;
	int int01 = 0;
	std::stringstream stream01;

	/* With userInput empty, the following code stops 
	the program	from functioning when it tries to output
	the stream01 stringstream object.  No error is
	generated.

	stream01 << userInput;
	std::cout << "userInput into stream01: "
		<< stream01.rdbuf() << std::endl;*/

	std::cout << "Type something: ";
	std::getline(std::cin, userInput);
	std::cout << "userInputString Previous to conversion: "
		<< userInput << std::endl;

	std::istringstream(userInput) >> doub01;
	std::cout << "istringstream conversion to double: "
		<< doub01 << std::endl;

	std::cout << "stream01.good(): ";
	if (stream01.good())
	{
		std::cout << "true";
	}
	else
	{
		std::cout << "false";
	}
	std::cout << std::endl;

	stream01 << userInput;
	std::cout << "userInput into stream01: "
		<< stream01.rdbuf() << std::endl;

	//while (!(std::stod(userInput)))
	//{
	//	std::cout << "Invalid entry." << std::endl;
	//}
	//doub01 = std::stod(userInput);

	std::cout << std::endl;
Last edited on
slightly tweaking the program from here to handle doubles: http://www.cplusplus.com/forum/beginner/206234/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <sstream>
#include <string>

int main()
{
    bool fQuit = false;
    while (!fQuit)
    {
        std::cout << "Give me a double ONLY\n";
        std::string choice;
        getline (std::cin, choice);
        std::stringstream stream(choice);
        double double_choice;
        if(!(stream >> double_choice) || static_cast<double>(stream.peek()) != std::char_traits <double>::eof())
        {
            std::cout<<"Incorrect entry, try again\n";
        }
        else
        {
            std::cout << "Success!!\n";
            fQuit = true;
            break;
        }
    }
}/


static_cast<double>(stream.peek()) != std::char_traits <double>::eof()
Why? The character representation has no relation to the type of data you're attempting to extract. Also, this looks like it would fail on entry of a value followed solely by whitespace which is not typically preferred behavior, although I concede it may be preferred by the OP.

@OP:
You might check out:
http://www.cplusplus.com/forum/beginner/108849/#msg592118
static_cast<double>(stream.peek()) != std::char_traits <double>::eof()
Why?
because peek() returns int and eof() returns bool, without the cast:
 
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
because peek() returns int and eof() returns bool, without the cast:

http://en.cppreference.com/w/cpp/string/char_traits/eof

I would expect something more like:

1
2
3
4
5
6
7
8
    // ...
        std::stringstream stream(choice);

        using char_type = decltype(stream)::char_type;

        double double_choice;
        if (!(stream >> double_choice) || stream.peek() != std::char_traits<char_type>::eof())
        // ... 

thanks again cire. your suggestion is undoubtedly more elegant and robust. i've updated my file with current post's link as this question pops up every now and then and will start spreading the message from now on
Topic archived. No new replies allowed.