I'm using the code as shown below
if(strcmp(oid, ".1.3.6.1.4.1.53864.1.1.0") == 0)
{
return 1;
}
else if (strcmp(oid, ".1.3.6.1.4.1.53864.1.2.0") == 0)
{
return 2;
}
...
else if (strcmp(oid, ".1.3.6.1.4.1.53864.1.n.0") == 0)
{
return n;
}
Now the problem is updated n value is 250. Can anyone please give me any idea to reduce this else if statement?
I tried to search on StackOverflow but those answers are related to the other languages and I want an idea that I can implement in the C language.
CodePudding user response:
This should do the trick. Do note that it's not completely equivalent. It skips checking for the ending ".0", but that's trivial to add if you want it. I also omitted the error check for sscanf
, but that's also easy to add.
char prefix[] = ".1.3.6.1.4.1.53864.1.";
if(memcmp(prefix, oid, sizeof prefix-1) == 0) {
int n;
sscanf(&oid[sizeof prefix-1], "%d", &n);
return n;
}
If you are very certain the strings are in the correct format, you can skip the memcmp
completely. Another approach, depending on your requirements is this:
sscanf(".%*d.%*d.%*d.%*d.%*d.%*d.%*d.%*d.%d.%*d", %n);
Do note that I'm using %*d for all but one integer. That means I'm reading them but not storing them.
CodePudding user response:
You can use strncmp()
to match the prefix (".1.3.6.1.4.1.53864.1."), extract the text value say by using strchr()
and convert it with strtol()
for the return, and match the suffix (".0"):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int oid_sub(const char *s) {
const char prefix[] = ".1.3.6.1.4.1.53864.1.";
if(strncmp(s, prefix, sizeof(prefix) - 1))
return -1;
char *end;
// check n for under and overflow?
int n = strtol(s sizeof(prefix) - 1, &end, 10);
const char suffix[] = ".0";
if(!end || strcmp(end, suffix))
return -1;
return n;
}
int main() {
char *s = ".1.3.6.1.4.1.53864.1.42.0";
printf("%d\n", oid_sub(s));
}
I would prefer a regex based solution:
#include <regex.h>
int oid_sub2(const char *s) {
regex_t r;
const char regex[] = "^\\.1\\.3\\.6\\.1\\.4\\.1\\.53864\\.1\\.([^.] )\\.0$";
if(regcomp(&r, regex, REG_EXTENDED))
return -1;
regmatch_t m[2];
if(regexec(&r, s, 2, m, 0))
return -1;
return atoi(s m[1].rm_so);
}
Note, atoi()
fails with 0 on error, so you could tweak the regex to ensure it matches numbers or use strtol()
as above (but no need to check the suffix as the regex already takes care of that).
CodePudding user response:
Looks like you want the value in the 2nd last field of the string.
Here's a rough cut. You should add checking before considering it done...
char *tmp = strdup( old );
char *lastSep = strrchr( tmp, "." ); // want to go back one more.
*lastSep = '\0';
*lastSep = strrchr( tmp, "." ); // now left of desired field.
int n = atoi( lastSep 1 );
free( tmp );
return n;
Or, if you want to "walk the string" left to right...
char *sep = old;
for( int i = 0; i < 9 && ( sep = strchr( sep, "." ) ) != NULL; i )
sep = 1;
return sep ? atoi( sep 1 ) : -1;
Or, simply count the separaters, stopping when you please.
for( int cnt = 0; *old && cnt < 9; )
if( *old == '.' && cnt == 9 )
return atoi( old );
return -1;