tags:

views:

239

answers:

5

Hi,

Is there a standard C function similar to strtol which will take a char* and a length for a non-null-terminated string?

I know that I could copy out the string into a null-terminated region, but for efficiency reasons that is undesirable.

Thanks.

A: 
Aditya Sehgal
And what happens if there happens to be numerical characters in the memory at the end of the non-null terminated string?
Eric
well good point. I havent thought of that.
Aditya Sehgal
@Eric: The point you raised would be a problem if the OP treats a combination of Numbers (like an existence of 3 8s together) as end of string. Other than that, strtol should work fine, right?
Aditya Sehgal
A: 

strntol is probably what you're after... it's not standard C, though.

Stobor
+2  A: 

No such function in the standard library. You will either have to use the temporary buffer method, or write your own function from scratch.

anon
A: 

If you're that pressed for efficiency, you can probably motivate the time to write and debug your own.

But: just do it with a copy; you probably have an upper bound for how long the string can be (a decimal numeral that fits in a long has a strict upper bound on its maximum length), so you can have a static buffer. Then profile your entire application, and see if the copying/conversion really is a bottleneck. If it really is, then you know you need to write your own.

Here's a rough (untested, browser-written) starting point:

long limited_strtol(const char *string, size_t len)
{
  long sign = 1;
  long value = 0;

  for(; len > 0 && *string == '-'; string++, len--)
    sign *= -1;

  for(; len > 0 && isdigit(*string); string++, len--)
  {
   value *= 10;
   value += *string - '0';
   len--;
   string++;
  }
  return sign * value;
}
unwind
A: 

To answer your question: no, there is no standard function, but it is simple enough to write your own:

#include <stdio.h>
#include <ctype.h>

int natoi(char *s, int n)
{
    int x = 0;
    while(isdigit(s[0]) && n--)
    {
     x = x * 10 + (s[0] - '0');  
     s++;
    }
    return x;
}

int main(int argc, char*argv[])
{
    int i;
    for(i = 1; i < argc; i++)
     printf("%d: %d\n", i, natoi(argv[i], 5));
}
iWerner