我想我在C命令行参数上有点生疏。我看了一下我的一些旧代码,但不管这个版本是什么让segfaulting。
运行它的方式是./foo -n num(其中num是用户在命令行中输入的数字)
但不知怎的,它不起作用。我哪里出错?
编辑:当我尝试访问atoi(optarg)时,它是segfaulting,这是atoi(0x0)的segfaults。
int main(int argc, char *argv[])
{
int c;
int maximum_n = max_n(); /* Stores the maximum value in the sequence a long can hold */
unsigned long *array = NULL;
while((c = getopt(argc, argv, ":n:")) != -1) {
switch(c) {
case 'n':
if(atoi(optarg) > maximum_n) {
printf("n is too large -- overflow will occur\n");
printf("the largest Fibonacci term than can be calculated is %d\n", maximum_n);
exit(EXIT_SUCCESS);
}
else {
array = fib_array(atoi(optarg));
}
break;
}
}
printf("The %d Fibonacci term is %lu\n", atoi(optarg), array[atoi(optarg)]);
return 0;
}
答案 0 :(得分:3)
与许多编程语言一样,在C argv[0]
中通常包含程序的名称。该值实际上取决于用于启动进程的exec*
系统调用的参数。出于您的目的,该部分无关紧要。需要注意的是,argc总是比程序在命令行上收到的参数数量大一个。在您的情况下,argc == 3
和argv
的值应该是
argv[0]: "./foo"
argv[1]: "-n"
argv[2]: "10"
你的程序是segfaulting的原因是你在optarg
不再有效之后访问它。每次拨打optarg
时,getopt()
的值都会发生变化。当您在while循环之外调用它时,它已更改为NULL
。当您处于atoi(optarg)
的切换案例时,您应该将'n'
的值存储到变量中。
由于您仍然对此感到困惑,我已使用必要的修补程序更新了代码。
int main(int argc, char *argv[])
{
int c;
int maximum_n = max_n(); /* Stores the maximum value in the sequence a long can hold */
unsigned long *array = NULL;
int n = -1;
while((c = getopt(argc, argv, ":n:")) != -1) {
switch(c) {
case 'n':
n = atoi(optarg);
if(n > maximum_n) {
printf("n is too large -- overflow will occur\n");
printf("the largest Fibonacci term than can be calculated is %d\n", maximum_n);
exit(EXIT_SUCCESS);
}
else {
array = fib_array(n);
}
break;
}
}
if (n == -1)
{
printf("You must specify a value with -n\n");
return 1;
}
printf("The %d Fibonacci term is %lu\n", atoi(optarg), array[n]);
return 0;
}
答案 1 :(得分:0)
问题在于:
printf("The %d Fibonacci term is %lu\n", atoi(optarg), array[atoi(optarg)]);
当getopt没有更多要处理的参数时,optarg
设置为NULL。函数atoi
没有正确的错误检查导致SIGSEGV。