verify input data

hello everyone,

I have a problem with a program I am trying to do in c ++ with visual studio 2019.

I have an int input variable that must be a number to move through a menu.

I fill this variable by reading the input cin on the screen and I want to check that in that input there are only numbers, I have checked that if I write letters or numbers that are not in the menu, it cleans the screen and requests the input again, if (! std: : cin) ...

But my problem is that if I enter numbers that are in the menu and letters all together, or separated by spaces, access the menu and I should discard that entry. if I enter letters and then numbers it doesn't happen

can someone help me try to read the post as a char and it gives me errors like
Run-Time Check Failure # 2 - Stack around the variable opc1 was corrupted

attached code:

#include <iostream>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <cctype>
#include <sstream>

int main()
{
int opc1 = 0;
while (opc1 != 3)
{
system("cls");
std::cout << "**************\n";
std::cout << "* 1 math op*" << std::endl;
std::cout << "* 2 help *" << std::endl;
std::cout << "* 3 exit *" << std::endl;
std::cout << "**************\n";
std::cin >> opc1;
if (!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
switch (opc1)
{
case 1:
[...]
system("pause");
break;
case 2:
[...]
system("pause");
break;
default:
break;
}
}
return 0;
}
Hello espcplusplus,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button. This will not automatically indent your code. That part is up to you.


You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.



You could try this:
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
do
{
    system("cls");

    std::cout <<
    "**************\n" <<
    "* 1 math op  *\n" <<
    "* 2 help     *\n" <<
    "* 3 exit     *\n" <<
    "**************\n"
    "Enter choice: ";
    std::cin >> opc1;


    if (!std::cin || (opc1 < 1 || opc1 > 3))
    {
        if (!std::cin)
        {
            std::cerr<<"\n     Invalid input! Must be a number.\n";

            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.

            std::cout << "\n\n Press Enter to continue: ";
            std::cin.get();
        }
        else if (opc1 < 1 || opc1 > 3)
        {
            std::cout << "\n     Menu choice invalid! Try again.\n";

            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
            std::cout << "\n\n Press Enter to continue: ";
            std::cin.get();
        }
    }

} while (opc1 < 1 || opc1 > 3);


Andy
Hello espcplusplus,

Looking at the "#include" header files:
1
2
3
4
5
6
7
8
#include <iostream>
#include <limits>
#include <string.h>  // <--- C header file. Should use "cstring".
#include <math.h>    // <--- C header file. Should use "cmath".
#include <stdio.h>   // <--- C header file. Should use "cstdio", but not needed
#include <stdlib.h>  // <--- C header file. Should use "cstdlib".
#include <cctype>
#include <sstream> 

"string.h" or "cstring" is a C header file and is not a replacement for the C++ header file "string".

Andy
Hello Andy,

First of all, thanks for responding. Also I thank you for the warning about the use of header files, since I am somewhat rusty in that regard and when I was taught to program I started with C. Then on my own I went to C ++ and I am refreshing everything.

I've tried your solution, it works fine, but it might not explain me well. I'm still having the same problem.

In my code, I have 4 possible entries:

letters: asdfasdf <- invalidates (OK)

numbers: 12341234 <- invalidate (OK)

numbers + letters: 1asdf <- accept as input 1 (error)

letters + numbers: p1234 <- in another point of the program that I do not include accepts input to (error)

What I try to do is that the code detects that it is not a valid entry, not that it only keeps the first character of the int or char variable, because if the first character belongs to a menu option, it accepts it without taking into account the rest of the characters.

I have been stuck with this for many days and for more things I do I only manage to generate more errors of operation, not code.

1 greeting
Read each line from cin with getline(). Then create a stringstream from the line, read the number, and attempt to read one more character to see if there is any junk after it.
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
#include <iostream>
#include <string>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <sstream>

using std::cin;
using std::cout;
using std::string;
using std::getline;
using std::istringstream;

int
main()
{
    while (true) {		// exit conditions are in the middle of the loop
	int opc1 = 0;
	string line;
	system("cls");
	std::cout << "**************\n";
	std::cout << "* 1 math op*" << std::endl;
	std::cout << "* 2 help *" << std::endl;
	std::cout << "* 3 exit *" << std::endl;
	std::cout << "**************\n";
	if (!getline(cin, line)) {
	    break;		// end of file
	}
	istringstream iss(line);
	if (!(iss >> opc1)) {
	    cout << "Please enter a number from 1 to 3\n";
	    continue;
	}

	// anything else on the line?
	char ch;
	if (iss >> ch) {
	    cout << "Error: extra stuff on input line. Please try again\n";
	    continue;
	}
	    
	if (opc1 == 3) {
	    break;		// exit
	}
	
	switch (opc1) {
	case 1:
	    cout << "User entered 1\n";
	    break;
	case 2:
	    cout << "User entered 2\n";
	    break;
	default:
	    cout << "Invalid entry. Please enter a number from 1 to 3\n";
	}
    }
    return 0;
}
Hello espcplusplus,

I can only comment on the code that you post. When you say:

In my code, I have 4 possible entries:

letters: asdfasdf <- invalidates (OK)

numbers: 12341234 <- invalidate (OK)

numbers + letters: 1asdf <- accept as input 1 (error)

letters + numbers: p1234 <- in another point of the program that I do not include accepts input to (error)


I can not see where this has anything to do with the menu. If you are trying to enter something other than a meny choice to use later in the program it will not work.

std::cin >> opc1; is formatted input and the first that is recognized is that "ppc1" is a numeric variable and expects you to enter a number. This is what the if statements are for because if you enter anything other than a number it will cause "cin" to fail and become unusable the rest of the program.

A letter, or non numeric value, will cause the cin to stop. Example: (1d2) will accept the (1) and stop at the (d) leaving the (d2\n) in the input buffer. The next time thru the loop it does not wait for keyboard input, but takes the (d) left in the input buffer causing "cin" to fail then the if statements will correct the problem and clear the input buffer before printing the menu again.

The code I showed you only deals with the menu input. If you are having a problem with code that you have not posted I need to see that part to see what is going wrong.

As I read your last post I have a feeling that you may be trying to use "opc1" for more than a menu choice and that is not what that part of your code is designed to do.

Andy
Topic archived. No new replies allowed.