Reputation: 95
I've been searching the internet for some time, but didn't find a simple solution for a actually simple problem in my eyes. I guess it has been asked already:
I'm reading a value like 20.1
or XYZ
via sscanf
from a file and saving it in char *width_as_string
.
All functions should be valid in -std=c99
.
Now I want to check if the value in width_as_string
is an integer. If true, it should be saved in int width
. If false, width
should remain with the value 0
.
My approaches:
int width = 0;
if (isdigit(width_as_string)) {
width = atoi(width_as_string);
}
Alternatively, convert width_as_string
to int width
and convert it back to a string. Then compare if it is the same. But I'm not sure how to achieve that. I already tried itoa
.
Functions like isdigit
and itoa
are not valid in std=c99
, therefore I can't use them.
Thanks.
Upvotes: 0
Views: 138
Reputation: 1
Read carefully some documentation of sscanf
. It returns a count, and accepts the %n
conversion specifier to give the number of character (bytes) scanned so far. Perhaps you want:
int endpos = 0;
int width = 0;
if (sscanf(width_as_string, "%d %n", &width, &endpos)>=1 && endpos>0) {
behappywith(width);
};
Perhaps you want also to add && width_as_string[endpos]==(char)0
(to check that the number is perhaps space suffixed, then reaching the end of string) after endpos>0
You could also consider the standard strtol which sets an end pointer:
char*endp = NULL;
width = (int) strtol(width_as_string, &endp, 0);
if (endp>width_as_string && *endp==(char)0 && width>=0) {
behappywith(width);
}
The *endp == (char)0
is testing that the end of number pointer -filled by strtol
- is the end of string pointer (since a string is terminated with a zero byte). You could make that more fancy if you want to accept trailing spaces.
PS. Actually, you need to specify precisely what is an acceptable input (perhaps by some EBNF syntax). We don't know if "1 "
or "2!"
or "3+4"
are (as C strings) acceptable to you.
Upvotes: 1
Reputation: 287
Actually, you could use sscanf at the very beginning to check whether the number is integer or not. Something like this
#include <stdio.h>
#include <string.h>
int
main (int argc, char *argv[])
{
int wc; // width to check
int w; // width
char *string = "20.1";
printf("string = %s\n", string);
if (strchr(string, '.') != NULL)
{
wc = 0;
printf("wc = %d\n", wc);
}
else if ((sscanf(string, "%d", &w)) > 0)
{
wc = w;
printf("wc = %d\n", wc);
} else w = 0;
return 0;
}
This is a sample program of course, it first searches the string for a "." to verify if the number could be float and discards it in such a case, then tries to read an integer if no "." are found.
Changed thanks to ameyCU's suggestion
Upvotes: 1
Reputation: 1517
How about strtol?
This gives a clear return value if something goes wrong, i think this is what you're looking for
http://www.cplusplus.com/reference/cstdlib/strtol/
Upvotes: 1