Validating Integer in C Programming - c

How can I make sure the number input by user is integer ranging from 0 to 4 only and also making sure that it is non negative/non symbol/alphabet??
If I do this,then it will not be able to validate alphabet/symbol
printf("Enter number 0 to 4");
scanf("%d",x);
if((x<0)||(x>4))
{
printf("0 to 4 only");
scanf("%d",x);
}
else
{
xxxxxx
}

First %d format from scanf expects a pointer to int. So you will write:
scanf("%d", &x);
Then you can test whether the read data match with the format, using scanf return value:
if (scanf("%d", &x) != 1 || x < 0 || x > 4)
{
/* Wrong input */
}
else
{
/* Well-formed input */
}
Read man scanf for further informations.

If the input should be a single number on the line, then:
char line[4096];
int x;
if (fgets(line, sizeof(line), stdin) == 0)
...EOF or other major trouble...
else if (sscanf(line, "%d", &x) != 1)
...not an integer...
else if (x < 0)
...negative - not allowed...
else if (x > 4)
...too large - maximum is 4...
else
...Hooray - number is valid in the range 0-4...use it...
You get to choose how the errors are handled. The first error handling should abandon the efforts to get a number from the user; the other three could warrant a retry (but keep an eye on how many retries you allow; if they get it wrong 10 times in a row, it is probably time to give up).
The key point is that the code uses fgets() to get the whole line, and then parses that. It would be possible to do further analysis — to make sure there isn't extra information on the line (so the user didn't type '3 dogs' instead of just '3'). This also allows you to report errors in terms of the whole line. The test for if (sscanf(line, "%d", &x) != 1) is also important. The members of the scanf()-family of functions report the number of successful conversion specifications (%d is a conversion specification). Here, if sscanf() successfully converts an integer, it will return 1; otherwise, it may return 0 or EOF (though EOF is unlikely with sscanf()). If there were 3 conversion specifications, the correct check would be != 3; it might report 1 or 2 successful conversions.

Related

Validation of integer inout and in general

How would I validate that the user enters a correct input, e.g. for an integer, since I am declaring the variables as ints before. (Meaning alpha would get numerical inputs.)
Also, is there a more general way of validating inputs and getting inputs; other than using scanf?
#include <stdio.h>
int main() {
printf("We will check if your number is odd, even, zero or negative \n");
int input;
printf("Enter your number: \n");
scanf("%d", &input);
if (input < 0){
printf("Number is Negative \n");
}
else if (input == 0){
printf("Number is Zero \n");
}
else if (input % 2 == 0){
printf("Number is Even \n");
}
else if (input % 2 == 1){
printf("Number is Odd \n");
}
return 0;
}
Using the scanf() family implies that the input is expected in perfect syntax for the conversion specifier given (in this case "%d" -> integer).
If you instead want to verify that correctness of the syntax of the input, then you need to take the input as a whole and then parse it yourself.
You can use e.g. fgets() (https://en.cppreference.com/w/c/io/fgets) to do so.
Once you have the input saved in a "string" (chars in an array or allocated memory), you can start "guessing" at what it is, using multiple sscanf() (https://en.cppreference.com/w/c/io/fscanf). This is much easier on a string which is already in memory than on the input stream. Because "wrong guess after partial success, try again from start" is easy in memory but hard on input.
As SomeProgrammerDude has already commented, the way to attempt scanning with sscanf() (in memory, or scanf() on input) is to check the return value; it will tell you about success or failure.

C sscanf() force number input

I'm trying to use sscanf() to validate commandline input
I want only things like 1, 0.1, 0.111 to go through,
not a12 12a or 1.2a
I tried
if (sscanf(input, "%f", &val) != 1) { // to check for 1 successful conversion
printf("invalid input");
}
but it seems like I'm letting invalid inputs go through as well.
Any advice?
When sscanf(input, "%f", &var) encounters the input 12a or 1.2a, it stops at the invalid input part, leaving the remaining characters available for reading by a subsequent format code.
Consider that the following strings have invalid characters for floating point numbers following a valid number:
1.0 2.0 (a space)
1.0, 2.0 (a comma)
1.0a 2.0 (a letter)
Spaces and commas look OK to our human parsing engine; the machine floating point parsing simply stops when an invalid character is found, whether it is a human acceptable space or comma, or an ugly letter.
If you want to ensure that a floating point number is not immediately followed by garbage, you could use something like:
n = sscanf(input, "%f%c", &var, &ch);
if (n == 1 ||
(n == 2 && (ch == ' ' || ch == ',' || ...))) {
// ...
}
sscanf is not your friend, here. Even if you check the result to
ensure that you read one whole argument successfully, that doesn't
really guarantee that the input is valid in a meaningful sense.
Given input like:
1!!!1!oneone!
the %f parsing will stop (but succeed) after reading the first 1,
and leave the read pointer at the following !. This may not be what
you consider "valid input".
If anything on the same line is to be considered garbage, then it gets
difficult, because scanf doesn't distinguish between spaces and
newlines. Perhaps try something like this:
int main(int argc, char *argv[])
{
float val;
char c;
if (sscanf(argv[1],"%f%c",&val,&c)!=1)
{
printf("invalid input");
}
return 0;
}
now it will validate all commandline input if it's floating number input or not.

vC: scan numeric input until EOF

I have an assignment, when in C programming language, I have to scan multiple numeric (just integer, if it's not integer, it should exit) values from keyboard. Values are divided by space and input is ended by EOF. I need to further work with these scanned values. I know maximum of putted numbers, I don't know beforehand how many numbers I'll get.
I tried:
while (scanf("%d", &a) == 1 && count <= 10000 ) {
eof=a;
if ( eof=getchar() == EOF ) break;
...
But it doesn't seem to work as I need (often you have to give EOF twice, but not always, and it sometimes adds 0 to the input). Same happens when I use just:
while (scanf("%d", &a) == 1) {
if I try:
while (... && (a=getchar()) != EOF) {
the variable a is rewritten and I can't work with it further.
Thanks in advance.
EDIT: Furthermore, I need to distinguish between EOF and invalid input (something other than number), which I am not sure how to do, because
scanf(...)==1
won't do that job.
Note the result of scanf() be it 0, 1,or EOF.
int count = 0;
int a;
int scnt;
while ((scnt = scanf("%d", &a) != EOF && count < 10000 ) { // not <= 10000
if (scnt == 0) {
// Handle stdin with unconvertible input. OP wants "it should exit"
puts("Bad");
exit (-1);
} else {
// Success! Let's print it
printf("%d %d\n", count++, a);
}
}
// why did we quit?
if (count >= 10000)
puts("Too many");
else if (feof(stdin)) {
puts("EOF detected");
else if (ferror(stdin)) { // rare
puts("IO error on detected");
else // Should never occur
puts("???");
Instead of scanning for integers, read the whole line at once using e.g. fgets, and then get the number from that.
Then you can easily just put the fgets call in the loop condition, and don't need any other check.
If fgets is impractical to use, then how about nested loops, one outer that ends on end-of-file condition (a special flag you set), and an inner that uses e.g. getchar to read all characters. If getchar returns EOF you set the flag for the outer loop and break out of the inner loop.
Of course, this means you have parse and put together the numbers yourself, but unless you have to handle larger numbers that can be handled by the normal standard types then it's trivial.

how to control input data format (C)?

anyone knows an efficient way to check out the format of an scanf'ed data?
e.g. if I try to read an integer and I type a character, how would you do to tell the program that is not correct?
You can check if scanf() succeeds, it returns the number of successful conversions it performed.
You should always check this, before relying on the result since if it failed the variable(s) might contain undefined data leading to undefined results if referenced.
You can use if to check, and re-try with a different conversion specifier on failure:
if(scanf("%d", &x) == 1)
printf("got integer %d\n", x);
else if(scanf("%c", &y) == 1)
printf("got character '%c'\n", y);
else /* more attempts */
Of course it can become troublesome if there are "sub-matches", so the order can matter. It's also way better to split the input processing into two steps for the above:
Read a full line of input using fgets()
Use sscanf() to parse the line
That way you avoid problems due to the input being streamed in:
char line[128];
if(fgets(line, sizeof line, stdin) != NULL)
{
int x;
char y;
if(sscanf(line, "%d", &x) == 1)
printf("got integer %d\n", x);
else if(sscanf(line, "%c", &y) == 1)
printf("got character '%c'\n", y);
}
Note that if you wanted to scan for both an integer and a float, it can still become troublesome since a typical float (such as "3.1416") begins with what is a legal integer. For those cases you can use the strtoXXX() family of functions, which let you check the remainder after doing the conversion.
As you have mentioned in the question that you are playing with numbers and chars only there is a very simple solution as follows
//while reading a char
scanf("%c",&temp);
if(!((temp >= 65 && temp <= 90) || (temp >= 97 && temp <= 122)))
printf("Only characters are allowed!\n");
hope this helps!
scanf("%s", &c);
if(!atoi(c)) puts("You have entered a character");
if(atoi(c) != 0) puts("You have entered an integer");
Scanner sc = new Scanner (System.in);
try {
// assume that the input from the user is not an integer,
// in that case the program cannot convert the input (which is a String) into
// an integer. Because of this situation it'll jump to the 'catch' part of the
// program and execute the code.
int input = Integer.valueOf(sc.nextInt);
// if the input is an integer lines below the above code will be executed.
// Ex. "int x = ( input + 10 ) "
}
catch (Exception ex) {
System.out.println("Invalid input, please retry!");
// if you want to get more information about
// the error use the 'ex' object as follows.
System.out.println(ex);
}

How to ensure user-input data is an integer

I am new to C, but I know C#. In C#, I could use TryParse to ensure that the user typed in the correct datatype.
Here is the basic code I have for C:
int shallowDepth;
do
{
printf ("\nEnter a depth for the shallow end between 2-5 feet: ");
scanf ("%d", &shallowDepth);
if (shallowDepth < 2 || shallowDepth > 5)
{
printf("\nThe depth of the shallow end must be between 2-5 feet.");
}
}
while (shallowDepth < 2 || shallowDepth > 5);
The problem is if I type characters, such as "asdf", the program goes crazy and repeatedly says "Enter a depth for the shallow end between 2-5 feet: ". I'm not sure why this is exactly happening, but it has to be because it expects an int and I'm passing characters.
So how do I verify that the user inputted data is of int type before trying to store it in a variable? Thanks.
This is happening because with %d scanf will refuse to touch anything that does not look like a number and leaves the text in the buffer. The next time around it will again reach the same text and so on.
I recommend that you ditch scanf for now and try something like fgets and then one of the functions in the strtoXXX family such as strtoul or strtoumax. These functions have a well-defined way of reporting errors and you can easily prompt the user for more text.
For example you could do:
char str[LENGTH];
long x;
if (!fgets(str, sizeof str, stdin)) {
/* Early EOF or error. Either way, bail. */
}
x = strtol(line, NULL, 10);
At this point you could use your number, but be aware that:
You can specify a pointer for strtol to fill and it will point to the first unacceptable character
If the result cannot be represented as a long then strtol will set errno = ERANGE. If you plan to test for this you must set errno = 0 before the strtol
If you want to use scanf you can't test it before. But you don't need too!
In your code if the user doesn't enter a number (or something that starts with a number), scanf returns 0, because it returns the number of parameters it could read.
So you need to check the return value of scanf to check if anything could be read.
Second, you need to remove everything that's still in the puffer.
You can use something like this for that:
while(getchar()!='\n');
If you want to handle files as well, you should catch EOF there, too.
int shallowDepth;
int invalid;
do {
int stat;
invalid = 0;
printf ("\nEnter a depth for the shallow end between 2-5 feet: ");
stat = scanf ("%d", &shallowDepth);
if(stat != 1){
invalid = 1;
while(getchar() != '\n');//clear stdin
} else if (shallowDepth < 2 || shallowDepth > 5){
invalid = 1;
printf("\nThe depth of the shallow end must be between 2-5 feet.");
}
}while (invalid);

Resources