2010-11-05 49 views
1

我有以下一段代碼:爲什麼atoi給我一個分段錯誤?

#include <stdio.h> 

int main (int argc, char *argv[]) 
{ 
    int M, N; 

    M = 1; 
    N = 1; 
    curr = 1; 

    if (argv[1][0] == '-') 
    { 
     curr = 2; 

     char *a = argv[1][1]; 
     char *b = argv[1][3]; 

     M = atoi(a); 
     N = atoi(b); 
    } 

    printf("%d\n%d", M, N); 
} 

所以,我通過這個程序是這樣的:

a.out -1,2 

,而不是如預期般輸出

我得到分段錯誤。是什麼賦予了?

+8

你使用了什麼破碎的編譯器? 'char * a = argv [1] [1];'應該給編譯器**錯誤**。 C沒有從'int'到指針類型的隱式轉換。 – 2010-11-05 17:18:59

回答

7

編譯?!

char argv * []是一個char指針數組。

char *a = argv[1][1]

  • 獲取第二字符指針,所以現在你有一個char *
  • 獲取該指針中的第二個元素,它將是一個char。

所以,現在你正在分配一個字符指針(這應該是一個編譯錯誤)。

我只能假設你的意思是說char *a = &argv[1][1]。順便說一句,常量正確性也不錯,所以const char *a = &argv[1][1]

順便說一下,你的代碼仍然非常不安全 - 你甚至不檢查字符串的大小。想象一下如果你的字符串只有兩個字符,&argv[1][3]會做什麼。

+1

沒有頭文件默認的假設是該函數存在(隱式聲明)作爲調用並返回一個int。這是警告在編譯器中作爲錯誤和高警告設置的好參數。 – Flexo 2010-11-05 17:18:57

+2

這不是關於這個函數,而是關於'char'到'char *'的賦值。 – EboMike 2010-11-05 17:20:28

+0

我假設他的意思是'char * a = argv [1] + 1;'或'&(argv [1] [1]);'' – Rup 2010-11-05 17:29:36

8

#include <stdlib.h>它應該變得明顯。

詳細說明:您將一個整數傳遞給需要指針的函數,編譯器無法警告您,因爲您忘記用原型聲明該函數。這是事故的原因。

此外,你只是錯誤atoiatoi解析字符串,而不是單個字符。如果你想要一個字符爲數字的值,只需減去'0'

M = argv[1][1]-'0'; 
N = argv[1][3]-'0'; 

在實踐中,你也應該檢查字符實際上是一個數字。

編輯:我不記得char *a = argv[1][1];在原崗位是(也許早編輯不會顯示爲編輯?),但任何理智的編譯器應該給在該行編譯時錯誤。整數不會隱式地轉換爲C中的指針。如果編譯器確實讓這個通過,那麼包含atoi的原型將不再有幫助,因爲類型錯誤發生得更早。

+0

我已經看到了自己對問題的神奇改變,而沒有被標記爲已編輯。幽靈般的。 – EboMike 2010-11-05 17:32:49

2

atoi需要一個字符串,而不是一個字符。

此外,atoi一般不好,因爲它基本上沒有錯誤報告。大多數情況下你應該調查strtol。

相關問題