在C中将命令行参数解析为无符号long

在C中将命令行参数解析为无符号long,c,command-line-arguments,unsigned-long-long-int,C,Command Line Arguments,Unsigned Long Long Int,我正在编写一个C程序,它接受一系列的无符号long数字作为命令行的输入。如何解析它们并存储在数组中?这似乎有帮助,但我该如何使用它呢 这是我的密码: #include<stdio.h> main (int argc, char *argv[]) { unsigned long long M[1000]; int i; printf("length: %d\n", argc - 1); for(i = 1; i < argc; i++) { M[i] =

我正在编写一个C程序,它接受一系列的
无符号long
数字作为命令行的输入。如何解析它们并存储在数组中?这似乎有帮助,但我该如何使用它呢

这是我的密码:

#include<stdio.h>

main (int argc, char *argv[])
{
  unsigned long long M[1000];
  int i;
  printf("length: %d\n", argc - 1);
  for(i = 1; i < argc; i++) {
    M[i] = strtoull(argv[i], NULL, 10);
    printf("%llu\n", M[i]);
  }
  return 0;
}
#包括
main(int argc,char*argv[])
{
无符号长M[1000];
int i;
printf(“长度:%d\n”,argc-1);
对于(i=1;i

当参数很小时,它可以工作,但当我输入一个很大的数字(比如123456789012345)时,它就不能正确解析。我做错了什么?

是的,您可以使用
strtoull
。下面是一个示例框架:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// include other headers as needed...


int main( int argc, char *argv[] )
{
    int i;
    unsigned long long big_value;

    // If there are no command line parameters, complain and exit
    //
    if ( argc < 2 )
    {
        fprintf( stderr, "Usage: %s some_numeric_parameters\n", argv[0] );
        return 1;
    }

    for ( i = 1; i < argc; i++ )
    {
        big_value = strtoull( argv[i], NULL, 10 );

        if ( errno )
        {
            fprintf( stderr, "%s: parameter %s: %s\n", argv[0], argv[i], strerror(errno) );
            return 2;
        }

        // Do some stuff with big_value

        ...
    }

    return 0;
}
#包括
#包括
#包括
#包括
//根据需要包括其他标题。。。
int main(int argc,char*argv[])
{
int i;
无符号长大_值;
//如果没有命令行参数,请投诉并退出
//
如果(argc<2)
{
fprintf(stderr,“用法:%s一些数字参数”,argv[0]);
返回1;
}
对于(i=1;i
一种简单的方法是使用argv[i]上的sscanf()和%llu解析无符号长整数。下面是一些示例代码:

#include <stdio.h>

int main(int argc, char *argv[]) {
    unsigned long long example;
    int i;
    for (i = 1; i < argc; i++) {
        sscanf(argv[i], "%llu", &example);
        printf("Argument: %llu\n", example);
    }
    return 0;
}
#包括
int main(int argc,char*argv[]){
无符号长示例;
int i;
对于(i=1;i

您也可以使用strtoull,事实上,我认为scanf()在内部使用它。不过要小心溢出,scanf()在适当的场合设置errno的表现不是很好。我有一些问题。但是您应该对unsigned long long保持冷静,您确实需要一个非常大的数字才能导致溢出。

请记住,命令行参数都是字符串。如果需要将任何值转换为数字(整数或实数),请查看手册页中的以下函数:

int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);
double atof(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
long long int strtoll(const char *nptr, char **endptr, int base);
double strtod(const char *nptr, char **endptr);
float strtof(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);

你没有包括在内。编译器没有警告您strtoull没有原型吗?未声明的函数被假定为返回一个
int
,而不是
strtoull
-1
strtoull
是正确的答案,
sscanf
对已知为数字的字符串来说是过火了。你并不是真的在帮助OP,他只是代码中有一个错误。给我看一些文档或链接,其中有详细的解释,我会编辑我的答案。对不起?我知道strtoull是stdlib.h的一部分。你看过我的评论了吗?我只是想问我在哪里可以读到scanf在解析数字方面做得太过火了。我读了你的评论,但显然你没有重读。你担心我的评论的哪一部分并不确切。关于过度杀戮的部分,我认为不需要参考。为什么要使用在运行时动态解析格式字符串的函数,因为有一个完美的解决方案可以直接执行此任务?这真的无关紧要,两个程序都同样有效。我试着用sscanf运行这个版本,每个数字从1到1000,然后计时。然后我把它改成使用strtoull,所用的时间也一样。您可以自己尝试,编写一个shell脚本以循环方式运行代码。也许您应该强调一个事实,即您对问题中代码的回答的主要区别在于使用了正确的头文件。当我运行此代码时,它似乎与我的原始代码有相同的问题。也就是说,如果通过命令行作为参数提供的数字太大(超过10位),如果我试图通过输入
printf(“%d:%llu\n”,I,big\u值)来打印它们,我会得到一个错误的值你现在有
。@MārisOzols很抱歉那是我的错。需要包含
stdlib.h
,因为它是
strtoull
的原型。我在编辑时无意中删除了它。我已经相应地更新了。我明白了,现在它工作正常了!我还尝试将
stdlib.h
添加到我的原始代码中,现在它也起作用了。我已经接受了另一个答案,但还是非常感谢@毛利苏佐尔不用担心
stdlib.h
是必需的,因为否则
strtoull
的返回值将被视为整数。编译器应该对此发出警告(gcc的默认设置是发出警告)。