【问题标题】:Is there a strtol equivalent that does not require a null-terminated string?是否存在不需要以空字符结尾的字符串的 strtol 等效项?
【发布时间】:2009-07-06 08:33:20
【问题描述】:

是否有一个类似于 strtol 的标准 C 函数,它将接受一个 char* 和一个非空终止字符串的长度?

我知道我可以将字符串复制到以 null 结尾的区域,但出于效率原因,这是不可取的。

谢谢。

【问题讨论】:

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

标签: c string std


【解决方案1】:

标准库中没有这样的功能。您要么必须使用临时缓冲区方法,要么从头开始编写自己的函数。

【讨论】:

    【解决方案2】:

    回答你的问题:不,没有标准函数,但你自己写很简单:

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

    【讨论】:

      【解决方案3】:

      strntol 可能是您所追求的……不过,它不是标准 C。

      【讨论】:

        【解决方案4】:

        如果您那么追求效率,您或许可以抽出时间编写和调试自己的代码。

        但是:只需复制一份即可;您可能对字符串的长度有一个上限(适合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;
        }
        

        【讨论】:

        • 在传递给isdigit之前,您应该转换为unsigned char
        猜你喜欢
        • 1970-01-01
        • 2011-06-06
        • 2020-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多