Check if a value from scanf is a number? - c

In the simplest way possible, how can I check if an integer initialized from function scanf is a number?

http://www.cplusplus.com/reference/clibrary/cstdio/scanf/
On success, [scanf] returns the
number of items succesfully read. This
count can match the expected number of
readings or fewer, even zero, if a
matching failure happens. In the case
of an input failure before any data
could be successfully read, EOF is
returned.
So you could do something like this:
#include <stdio.h>
int main()
{
int v;
if (scanf("%d", &v) == 1) {
printf("OK\n");
} else {
printf("Not an integer.\n");
}
return 0;
}
But it is suggest that you use fgets and strtol instead.

Your question is weirdly worded. An initialized integer is always a number (aside from exotic cases of trap representations), which means that there's no need to check anything.
I would guess that you need to check whether the given string is a valid representation of a number. For that, you first need to define what the valid representation should look like. Do you allow sign? Is a redundant + allowed (as a sign)? What about 0x prefix for hexadecimals? And so on.
C language offers its own set of rules that define the language's idea of a valid string representation of an integer. If that's what you need, then in order to verify whether the given string satisfies these rules, the best way is to use string-to-integer conversion function like strtol (and other functions from strto... group) and then check for the error condition.
Beware of the answers that suggest writing your own function that would verify these rules. This just doesn't make any sense, since the standard function exists already. Also, strictly speaking, in real-life programming there's rarely a need to perform verification without the actual conversion. strto... will do both.
Also, stay away from functions from scanf group to perfrom string-to-integer conversion. These functions produce undefined behavior on overflow (i.e. if the input string representation is too long). In general case, the only proper way to do such a conversion in C is functions from strto... group.

Related

Why does scanf return a positive value even when the input is larger than the numercial type given?

Given the following code :
int x;
int r = scanf("%d", &x);
why is scanf returning 1 when the user inputs a number larger than INT_MAX or even larger than LONG_MAX?
From the documentation:
Number of receiving arguments successfully assigned.
Why is x considered successfully assigned? What does it mean exactly in this context? When the user gives numbers between INT_MAX and LONG_MAX, x appears to be the lower half of the result. I know scanf uses strtol internally but scanf could determine that the type int is too small to contain the result. Further, when passing a giant number, larger than LONG_MAX, the value of x is -1 and the return value is still 1 and I have to rely on errno to check that something went wrong (errno == ERANGE).
What does "successfully assigned" mean and why does scanf return 1 given that it could so easily tell that the result is, in fact, garbage?
Unfortunately you cannot rely on errno == ERANGE or such in portable C programs.
fscanf is not documented authoritatively on cppreference.com, but in the ISO C standard. Firstly, the standard states that
The fscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.
I.e. nowhere does it contain the word "successful".
On the contrary, it says:
[...] if the result of the conversion cannot be represented in the object, the behavior is undefined.
I.e. unfortunately there are no guarantees of behaviour in this case. In particular the standard never states that the result would be the largest number, or that errno would contain ERANGE or any other such thing.
why is scanf returning 1 when the user inputs a number larger then INT_MAX or even larger than LONG_MAX?
It is undefined behavior (UB) when the input text converts to outside the int range for "%d". It is a specification weakness of scanf().
Anything may happen.
Robust code separates input from conversion. Look to fgets() and strtol().
"scanf" is a function that reads data with specified format from a given string stream source. It allows the programmer to accept input from the standard input device (keyboard) and stores them in variables.
"scanf" stands for 'scan format', because it scans the input for valid tokens and parses them according to a specified format.
Reads a real number that (by default) the user has typed in into the variable miles
Each variable must be preceded by the ampersand (&) address-of operator.
We can read values into multiple variables with a single scanf as long as we have corresponding format strings for each variable.
"scanf" successfully accomplishing the 'scan format' function. It's not the function of "scanf" to check for the range for corresponding datatype.
Remember that scanf (and its brothers and sisters) is a variadic function. There's value in telling the caller how many arguments were successfully assigned, where "successfully" might mean less than you think it does. It's the responsibility of the caller to make sure the arguments agree.

why does this C/C++ code helps in taking fast input

I took this code from this link https://www.codechef.com/viewsolution/1715623
and I am not able to understand how the scan() function helps in taking fast input
#define g getchar_unlocked()
int scan()//fast input output
{
int t=0;
char c;
c=g;
while(c<'0' || c>'9')
c=g;
while(c>='0' && c<='9')
{
t=(t<<3)+(t<<1)+c-'0';
c=g;
}//end fast input output
return(t);
}
User defined function scan() uses lib function getchar_unlocked() which is faster than getchar() and any other standart input methods since it's not thread safe.
Inner function loops are used to consider only numeric input (and uses shift operators instead of multiplying for extra performance gain which must be tested before used).
And this function contains possible int overflow.
I think it's basically atoi with getchar. It ignores leading non numeric characters then creates an integer of the string numerals, exiting when numeric numbers stop. Scan is probably not the right name for this, it should be Atoi(), or ScanNum()? Probably doesn't work for when the integer is big due to integer overflow issues.
I'd be surprised if this is faster than atoi() not sure why they didn't use isdigit() either.
Unlike the California University code, doesn't check for a sign, nor does it use the register keyword.

format specifiers in scanf( ) in C?

Why do we pass the format specifiers to scanf( ) in C as its parameters?
I mean, can't we just do
scanf( &var ); // Here, var is any pre-declared variable.
the type of var can be fetched from its declaration. Why is this not allowed ?
I see the below code as a waste of memory.
scanf( "%d" , &var );
The type cannot be "fetched from it's declaration". There is nothing magical about scanf(), it's just a function. A function in C cannot access meta information about variables.
This is why, in general, function arguments are declared including their type. For variable-argument functions such as scanf(), the first argument is not optional and it is used to describe the number and type of the other arguments in some fashion chosen by the function itself.
You clearly need to read some book on C programming to get better understanding of the core concepts. Unlike some other languages, C doesn't have I/O mechanism baked into the language. scanf() is just a library function and as such, this function has no way to automagically know the type of the variable it is supposed to fill.
Because %d will simply specify what the type of var is, there is no memory wastage. scanf(&var) would not work because the function is not designed to accept arguments that way.
You know that variables in C can be of different types:
int: Integer
char: Character
float: Floating point number.
...
Unlike other languages, variable types cannot be implicitly inferred at compilation time in C. That is why you always declare the type of your variables ( Example: int a or char c).
Because scanf is just a function in C, and because functions in C should take parameters of a specific type, people who coded C decided to use the following format:
scanf("%d", &var) ; // for integers
scanf("%c", &var); //for chars
scanf("%f", &var); //for double and floats.
using %d or %c does not waste memory or whatsoever. you can think about it as a flag that specifies the type of the input variable.
Could the developers of C do it without %d, %c...etc? Yes they could, but then, they have to handle all possible exceptions that might arise from sending the wrong type.
Suppose the developers of C used just the following format
scanf(&var);
That is surly very concise, but then you will have to use the same syntax to send chars/int/double...etc, and then the function scanf has to figure out a way to decide about the type of the variable that was sent. Remember what I told you before? variable types CANNOT be implicitly inferred at compilation time, and thus, this task will be almost impossible.
They could however use a different scanf function for every type. For example:
scanfInt(&var); //for integers.
scanfFloat(&var); //for floats.
...
...
That would work perfectly, but it makes less sense to replicate the same code of scanf and use different functions just because the type is different.
So what is the solution? ==> Use the same function name ( scanf ), and then add a parameter (%d, %f, %c..) that will be used internally as a flag by C to know the parameter type.
I hope now you have a better understanding of the use of %d, %f....
There are two major points you are missing here.
First, we humans sitting at the keyboard will write something like:
char var = '0';
And we know that the "type" of this variable is char and we probably intend to store a character there. Once the compiler gets a hold of this it removes these "human" elements all that is left is at some memory location there is 1 byte reserved, further references to places in the code where we wrote "var" will interact with this memory location. That is all the compiler knows, there is no understanding of the intended variable "type".
Second, the format specificers do so much more than just indicate a simple type. Look at any page explaining scanf() and you'll see a long list, take special note of things like scan sets, negated scan sets, and expected input lengths.
Let's say I want the user to enter just a single digit, 0-9, well I don't have to just assume they will do as I ask, I can help ensure they will by using the format specifiers in scanf():
int var = 0;
print("enter 1 digit (0-9):\n");
scanf("%1d", &var);
Now, no matter how many digits they enter, I'll only have stored the first one.
What if you have a string that you want to read from the user, and you want to read everything up until you hit a new line character (read over spaces). We'll there are a number of options for this, but scanf can do it too. The "standard" to read a string is:
scanf("%s",some_string);
But that will stop at any whitespace character, so you wouldn't want scanf() to make an assumption in this case, you'd want to be able to use a specific negated scanset:
scanf("%[^\n]",some_string);

C: Ways to use scanf

Can I use scanf(...) as argument to a function ?
Like this:
printInteger(scanf(....));
Can I use scanf to attribute the value that I read to some variable ?
Like this:
n = scanf(...);
p.s.: Here I'm explaining why I'm asking this.
This question can be a little weird I know, but I'm working in a project, which is developing a compiler that takes some language as input and then compile to C.
For example, this is my language, let's call 'stackoverflow' ;)
proc printInteger(integer k)
integer i;
begin
for i = 1 to k do
print i;
end
proc main()
integer n, i;
boolean ok;
begin
printInteger(getInteger);
n = getInteger;
ok = true;
while i < n do
begin
print i;
i = i + 1;
end
if ok then print 1; else print 0;
end
I won't get deeper in the language, but notice that getInteger means that I would like to do a scanf(...), what I mean is, when appears getInteger I would like to compile as scanf(...), so that's why I would like to know some ways to use scanf(...).
Can I use scanf(...) as argument to a function ? Like this:
printInteger(scanf(....));
Can I use scanf to attribute the value that I read to some variable ? Like this:
n = scanf(...);
You can use scanf as an argument to a function, but the real answer to both questions is no: scanf doesn't return any data scanned, it returns the number of items successfully scanned - or EOF if the end-of-input is reached before any successful scanning. You only get access to the items scanned using the pointers that you pass as scanf arguments to receive the values. So while you can pass scanf as an argument to a function, it won't do what you seem to want.
If you want to implement the getInteger operation in your language, in C, it's hard to make suggestions since only you know how this language/operation should work. Just using scanf, the implementation would look something like this:
int nextInt;
int numScanned = scanf("%d", &nextInt);
if (numScanned < 1)
handleError();
return nextInt;
But if you're doing general parsing for your language, then using scanf is a bad idea: you'll soon run into problems with the limitations of scanf, and you're not going to be able to anticipate all of the input types unless your language is really simple, simpler than the example that you've included.
To do this properly, find a good lex library for C. This will prevent a lot of headaches. Otherwise, if you must do the lexing yourself, start looking over fgets, get a line at a time from your input, and do the tokenizing yourself.
You ask:
Can I use scanf(...) as an argument to a function like this?
printInteger(scanf(....));
The answer to the first question is "Yes, but ...".
Can I use scanf to attribute the value that I read to some variable like this?
n = scanf(...);
The answer to the second is "No, because ...".
The "but" is mostly 'but it does not do what you expect so you would very seldom, if ever, do so'.
In the first example, scanf() returns either the (integer) number of successful conversions, or EOF if it reached EOF. In no case does it return the value that it just read (not least because, in general, it reads multiple values and most of them are not integers). So, if you want to print the number of values that was converted, you could use the printInteger() function to do so, but it is not what you'd normally want to do.
Similarly, in the second case, you can certainly assign the result of scanf() to an integer n as shown (and it is often sensible to do so if you're going to need to report an error). However, that is not the value that was read (assuming you had a %d conversion specification); it is the number of successful conversions.

Having scanf in C return void instead of int

If I have a program that is using scanf to get user inputted data:
scanf("%d",&val);
When I run it through lint I get warnings saying that scanf returns a int and it is not being assigned anywhere. What is the c practice to solve this problem? Do I type cast it as void?
(void)scanf("%d",&val);
The C best practice to solve this warnings is simple: Check the resultcode. The scanf function returns in the int if the operation has gone ok or not, and stores the error usually in errno.
The lack of resultcode checks usually results in big errors in certain situations.
The proper answer, of course, is to not ignore the return value. For a robust program, you should always (EDIT: usually) check that the return value indicates success, and fail gracefully when it does not.
Ideally you would do something like
int scanVal = scanf("%d", &val);
if (scanVal != 1) {
// wait a minute, scanf couldn't match input to a "%d"!
}
and then act on the output in a sensible manner.
Instead of silencing the lint message, just check the return value to make sure nothing has gone wrong. From the man page:
RETURN VALUE
These functions return the number of input items
successfully matched and assigned, which can be
fewer than provided for, or even zero in the event of an early
matching failure.
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs. EOF is also >returned if a read error occurs, in which case the
error indicator for the stream (see ferror(3)) is set, and
errno is set indicate the error.
scanf returns the number of input items successfully matched and assigned. Compare its return value to the number you expect in order to detect errors.
while (scanf("%d",&val) != 1)
printf("Try again.\n");
Use
#pragma warning(disable:<warning number>)
scanf("%d",&val);
#pragma warning(default:<warning number>)
And your compiler will suppress that warning.
The best practice is to assign the return value of scanf to see if all (or how many) items were read. In this particular case, if it returns anything but 1, something went wrong (e. g. you wanted a number but the user is giving you unprintable characters) and you should handle it appropriately.
If you want your code to be robust in the presence of bad input, don't use scanf("%d", ...).
For most errors, scanf("%d", &val) will return 0 to indicate that it wasn't able to read an int value (for example, if the input is "foo" rather than "123").
But if the input is syntactically valid but out of range (for example 9999999999999999999), the behavior is undefined.
Most implementations will probably behave sanely, but I don't know how much consistency there is.
To read an int value safely, use fgets() (not gets()) followed by strtol(). (fgets() can have problems with very long input lines, but there are ways to deal with that.)

Resources