Reputation: 2441
I have a program that accept orders by reading commands from a file. In this file some commands are "float string", like "1.0","2.0", but they are invalid, what the program need is integer, like "1","2". So, how can I make the program understand the commands like "1.0" is invalid? Is there any neat way to do this?
char buf[CMDSIZE];
if(fgets(buf, CMDSIZE, stdin)) //buf likes this: "1.0 \n"
{
*prio = 1; *command = -1; *ratio =1.0;
// I need to make sure that command is not "1.0" or something like this
sscanf(buf, "%d", command);
switch(*command){....blahblah......}
}
Thank you.
Upvotes: 0
Views: 1971
Reputation: 3
You can use scanf with %f to store it as a floating point value example or scan with %d to store it as an integer but it will not count the decimal
#include<stdio.h>
main()
{
float i;
int a;
printf("Enter a number which is a floating point value");
scanf("%f,%d",&i,&a);
}
here using scanf and %f we are storing it in a float variable i so 1.5,1.0 or any number with a decimal will be stored or if we only use the %d it will only store 1,2,3,4 any number without the decimal i.e if we give 2.5 it will only take 2
Upvotes: 0
Reputation: 3678
in your special case, just to check difference between 1 and 1.0 use the code:
int ret = scanf("%d.%d",&i,&j);
if inputs is 1, the scanf only assign one value, the ret is 1 if inputs is 1.0, the scanf assign two value, the ret is 2. if inputs is abcd, the scanf can't assign any value, the ret is 0
and regarding the return value of scanf, fscanf etc.
In C99 standard 7.19.6.4 The scanf function
The scanf function returns the value of the macro EOF if an input failure occurs before any conversion. Otherwise, the scanf 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
Upvotes: 0
Reputation: 213318
It's easier to use strtol
.
This will parse a base-10 integer. The pointer e
will point to the first character after the integer. You can check to make sure it's a NUL byte and signal an error otherwise. (You also have to check that the input isn't empty.)
If you want to allow spaces / newlines after the number, you can do that too. Note that strtol
eats leading whitespace -- but not trailing whitespace.
long v;
char *e;
v = strtol(buf, &e, 10);
if (!buf[0] || *e) {
error();
}
// v has number
Footnote: Checking for overflow and underflow with strtol
is a little weird. You have to set errno
to 0 first, call strtol
, then check if the result is LONG_MIN
or LONG_MAX
and if errno
is set to ERANGE
.
Upvotes: 3
Reputation: 27632
Both scanf("%d"....)
and scanf("%f"....)
will succeed and return 1 when reading the input 1.0. (sscanf works the same way.) It's just that with "%d"
, it will stop reading before the decimal point.
You can use the format specifier %n
with sscanf to see how many characters were read, and then look if the buffer contains more stuff afterwards.
Or, which might be easier, just look at the contents in the buffer with your own code, instead of sscanf, to see if there are only digits there.
Upvotes: 3