错误C3861:'strtoll':找不到标识符

时间:2011-11-23 08:18:47

标签: c visual-studio-2010 strtol

我在这里面临的主要问题是strtoll()在VC 2010中被标记为错误(error C3861: 'strtoll': identifier not found)。如果我用strtol()替换它会做同样的事情吗?

unsigned int get_uintval_from_arg(int argc, int index, char **argv,
                                  unsigned int lower_bound, unsigned int upper_bound) 
{  
    unsigned int return_val=0;

    if (index + 1 <= argc - 1)
    {
        return_val=(unsigned int)strtoll(argv[index+1],NULL,10);
        if (errno == EINVAL || errno== ERANGE) 
        {
            fprintf(stderr, "Could not parse argument %s for switch %s!\n",
                    argv[index], argv[index+1]);
            return 0;
        }
    }
    // ....... I will post the remaining part of the code if necessary 
    .......
}

4 个答案:

答案 0 :(得分:5)

由于您的return_valunsigned int,您可能应该使用自{C89以来已成为标准版的strtoul(),因此受MSVC支持(而strtoll()仅支持errno自C99以来的标准,MSVC不支持。

您对错误条件的测试是不够的。在调用转换函数之前,您需要将strtol设置为零;你还需要检测是否报告了错误,这比看起来更棘手。

第§7.20.1.4节'C99标准的strtol,strtoll,strtoul和strtoull函数'表示:

  

<强>返回

     

strtollstrtoulstrtoullerrno函数返回转换后的内容   价值,如果有的话。如果无法执行转换,则返回零。如果值正确   超出可表示值的范围,LONG_MIN,LONG_MAX,LLONG_MIN,   返回LLONG_MAX,ULONG_MAX或ULLONG_MAX(根据返回类型   和值的符号,如果有的话),宏ERANGE的值存储在endptr

您还必须阅读存储在转换函数的nptr参数中的值,以告知没有执行转换(与转换的有效零相反)。

  

如果主题序列为空或没有预期的形式,则不进行转换   执行; endptr的值存储在endptr指向的对象中,提供   <{1}}不是空指针。

所以,你必须编写更像这样的代码(省略针对EINVAL的测试,因为标准没有提到将errno设置为EINVAL的这些函数):

unsigned int return_val=0;

if (index + 1 <= argc - 1)
{
    char *end;
    unsigned long ul;
    errno = 0;
    ul = strtoul(argv[index+1], &end, 10);
    if ((ul == 0 && end == argv[index+1]) ||
        (ul == ULONG_MAX && errno == ERANGE) ||
        (ul > UINT_MAX))
    {
        fprintf(stderr, "Could not parse argument %s for switch %s!\n",
                argv[index], argv[index+1]);
        return 0;
    }
    retval = (unsigned int)ul;
}

请注意,这比有符号整数转换的测试更简单,该转换必须考虑负<type>_MIN限制以及<type>_MAX限制。

另请注意,您确实应该将结果记录在unsigned long中,然后检查它是否适合您指定的范围,该范围可能仅限于UINT_MAX(在Unix类64中可能小于ULONG_MAX-位环境)。

答案 1 :(得分:1)

在Visual Studio中使用_strtoi64()方法。它与strtoll具有相同的参数。

为了兼容性,您只需使用define将其包装为strtoll(如果您需要可移植性),例如

#if defined(_MSC_VER)
#define strtoll _strtoi64
#endif

答案 2 :(得分:0)

strtol()long的正确库函数。为了便于携带,请将return_val声明为long或unsigned long。如果是后者,请查看MSVC是否提供strtoul()

答案 3 :(得分:0)

出于您的目的,您应该使用strtoul,因为您要转换为unsigned long类型,而不是signed long long类型(strtoll将会执行此操作)。如果您需要阅读long long,请使用特定于Microsoft的_strtoi64;您可以使用#define在Microsoft平台上将其重命名为strtoll,或者在特定于Windows的可移植性填充程序文件中编写包装函数(在私有标头中使用您自己的原型)。