2010-10-16 121 views
0

当我尝试在命令行上将一个数字传入我的应用程序时,在下面的代码中出现奇怪的分段错误。isdigit()分段错误

int offset = 3; 

int main(int argc, char *argv[]) { 
    // Check for arguments to see whether there is a custom offset 
    if (argc == 2) { 
     // If argc == 2 then we have a offset? 
     if (isdigit((unsigned char)*argv[1])) { 
      offset = atoi(*argv[1]); 
      printf("Offset changed to: %d\n", offset); 
     } else { 
      printf("Offset not changed due to %s not being a number.\n", *argv[1]); 
     } 
    } else if(argc >= 2) { 
     // If argc >= 2 then we have too many arguments 
     printf("Too many arguments."); 
     return 0; 
    } 
} 
+3

我首先在'* argv [1]'中使用圆括号。它定义了一个独特的操作序列,但我不相信自己知道哪一个。 – 2010-10-16 21:24:53

+0

为什么'(unsigned char)'为类型'char'强制转换为'int'并将其传递给'isdigit(int)'? – msw 2010-10-16 21:25:36

+0

我在网上阅读了一个教程,需要将其转换为(无符号字符)...无论使用什么变体,我都会得到分段错误... – Aran 2010-10-16 21:27:13

回答

4

的argv [1]已经是(的类型char *)的字符串,所以写* argv的[1]解引用到通过该字节时引起的段错误给atoi第一字节()和printf() 。

解决它:

offset = atoi(argv[1]);

printf("Offset not changed due to %s not being a number.\n", argv[1]);

+0

仍然分段错误: -/ – Aran 2010-10-16 21:28:49

+0

ups,错误的行固定:)现在它应该工作 – cytrinox 2010-10-16 21:30:07

+0

@Aran:你提供什么样的参数? – 2010-10-16 21:30:29

2

的问题是ATOI呼叫。它期望一个字符串。将其更改为

offset = atoi(argv[1]); 
+0

Aran仅检查第一个字符是否是数字。像0Saurabh这样的说法仍然是无效的。 – 2010-10-16 21:31:29

+1

它会将字符串的起始部分转换为0。不清楚这是否是提问者想要的内容,但它不会再导致分段错误。 – 2010-10-16 21:37:19

5

真正问题,你的代码是你试图调用您没有宣布(你必须使用一个C89/90的编译器)功能。您致电isdigit。您致电printf。您致电atoi。你错误地称后两个。编译器无法通知您这些函数被错误地调用的唯一原因是您忘记声明它们。

包括<ctype.h><stdlib.h><stdio.h>在源文件的开头,让编译器知道正确的参数类型atoi等功能。一旦你这样做,你应该能够找出atoi的问题,因为编译器会发出解释问题的诊断信息。然后您可以相应地更改呼叫。一些编译器也可以通过printf调用来检测问题。

注意,即使你改变atoiprintf电话在其他的答案建议(即atoi(argv[1])等),你的代码将依然无效,因为在C89/90调用printf没有首先声明它会导致未定义行为(并且在C99中,如果不先声明它,则调用任何函数都是非法的)。

+0

编译器会告诉你,如果你使用'-Wall'编译,你试图调用你没有声明的函数。 (或本地等价物,但引用分割错误表明Unix和GCC或其他兼容选项) – 2010-10-16 21:58:44

+0

我有所有必要的包括,我只是排除它们以减少复制的代码量... – Aran 2010-10-17 19:29:40

+0

@Aran:如果你有所有必要的包含,那么你是如何编译你的'atoi(* argv [1])'?任何C编译器都会在需要指针值时尝试传递'char'值来引发各种各样的地狱。 – AnT 2010-10-17 19:42:48

1
#include <ctype.h> 
int isdigit(int c); 

ISDIGIT()期望单个字符来检查,的argv []是指向字符串(字符的数组)。长话短说,它不会检查像“1234”字符串,但它会检查'1'