2010-10-16 123 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'