Reputation: 7705
Im using sscanf to read/parse a 3 char string into an int as:
char strId[4] = "123";
int i;
int count = sscanf(strId, "%i" &i);
Im testing count==1
to check if the parse suceeds or fails.
"123"
suceeds correctly - I want to consider this a number.
"aaa"
fails correctly - I don't want to consider this a number.
but
"2aa"
suceeds (count==1, i==2)- but I would like to identify this as a failure as I don't want to consider this a number.
How to simply parse strId to meet the above conditions?
Upvotes: 1
Views: 201
Reputation: 153303
A sscanf()
approach, use "%n"
.
"%n"
saves the location where scanning stopped.
char strId[4] = "123";
int n = 0
sscanf(strId, "%i %n" &i, &n);
if (n == 0 || strId[n] != '\0') Handle_ProblemInput(strId);
This will pass: "123"
, " 123"
, "123 "
.
And fail: "123a"
, ""
, " abc"
.
May/may not detect int
overflow "12345678901234567890"
.
[Edit]
What is nice about the "%n"
is that it can be used with complicated formats and with formats that otherwise end with fixed text. IOWs, simply detect if the scan made it all the way to '\0'
?
int n = 0;
sscanf(buf, " %i %f %7s ,,, %c blah foo %n", ...);
if (n == 0 || buf[n] != '\0') Handle_ProblemInput(buf);
Upvotes: 2
Reputation: 8830
char str[255];
int count = sscanf((const char*)strId, "%i%254s", &i, str);
if it comes back with count == 1
it is okay?
Upvotes: 0
Reputation: 53006
With strtol
that's an easy task just do this
#include <stdio.h>
#include <stdlib.h>
char string[] = "123xyz";
char *endptr;
int value;
value = strtol(string, &endptr, 10);
if ((*string != '\0') && (*endptr == '\0'))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
If you want to use sscanf()
then this should do it too
#include <stdio.h>
#include <string.h>
char string[] = "123";
int count;
int value;
int length;
length = strlen(string);
if ((sscanf(string, "%d%n", &value, &count) == 1) && (count == length))
printf("%s is a number and has no unconvertible characters", string);
/* and now 'value' contains the integer value. */
Upvotes: 1
Reputation: 4449
Use strtol(3)
. It allows specification of an "end-of-parsing" pointer (endptr
below). After the conversion has finished you can check wether or not it points at the end of string. If it doesn't, there were non-number characters left in the input.
long strtol(const char *restrict str, char **restrict endptr, int base);
From man strtol
:
If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, however, strtol() stores the original value of str in *endptr. (Thus, if *str is not '\0' but **endptr is '\0' on return, the entire string was valid.)
Upvotes: 2