有没有类似于strtol的函数,它不需要以空字符结尾的字符串作为参数?

11

是否有类似于strtol的标准C函数,可以接受一个非空结束字符串的char*和长度作为参数?

我知道我可以将字符串复制到一个null-terminated区域,但出于效率考虑,这是不可取的。


3
嗨,我来自未来。你相信10年后仍然没有标准解决方案,不需要将字符串复制到临时缓冲区吗?还记得2000年播出的辛普森一集中特朗普是美国总统吗?如果我告诉你,你肯定不会相信... - user1593842
如果您愿意使用C++标准库,https://en.cppreference.com/w/cpp/utility/from_chars 是一个不错的解决方案。 - user406009
4个回答

4
回答您的问题:没有标准函数可用,但编写自己的函数非常简单:
#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));
}

4

标准库中没有这样的函数。你要么使用临时缓冲区的方法,要么从头写一个自己的函数。


2

strntol 可能是你需要的... 尽管它不是标准 C。


1

如果你非常追求效率,你可能可以找到时间编写和调试自己的代码。

但是:使用复制方法来完成它;你可能已经有了字符串的最大长度上限(适合于long数据类型的十进制数字具有严格的最大长度上限),因此你可以使用静态缓冲区。然后对整个应用程序进行性能分析,查看复制/转换是否真的成为瓶颈。如果确实是,那么你就需要自己编写代码。

这里有一个大致的(未经测试的、由浏览器编写的)起始点:

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;
}

2
在传递给 isdigit 之前,您应该将其转换为 unsigned char - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接