2013-10-21 28 views
0

我可能完全是這樣做的,但考慮到這將是個人使用,如果不是那麼高效就沒關係。不使用自變量時出現分段錯誤(核心轉儲)

當作爲./todo -r運行時,它工作。

當作爲./todo -a運行時,它工作。

當爲./todo跑了,這讓我segmentation fault (core dumped)

#include<stdio.h> 
#include<stdlib.h> 

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

    if(argc < 1) { 
    printf("Not enough variables."); 
    } 

    if(strcmp("-r",argv[1])==0) { 
     printf("\n"); 

     system("cat .todo"); 
     printf("\n"); 
    } 
    if(strcmp("-a",argv[1])==0) { 
    char str[BUFSIZ]; 
    FILE *f; 
    f = fopen(".todo","a"); 
    printf("\n\nTODO list\n\n"); 
    for(;;) { 

     printf("~ "); 
     fgets(str,256,stdin); 
     if(strcmp(str,"\n")==0) { 
      fclose(f); 
      printf("\n"); 
      break; 
     } 

     fprintf(f,str); 
     } 
    return 0; 
    } 
} 
+1

'如果(ARGC <1)' - 應該是'如果(ARGC <2)'。 –

+0

還需要檢查fopen的返回值爲0. –

+1

提示:將代碼粘貼到SO時,請先移除標籤。正如你所看到的,在問題代碼中的縮進不是很正確...... – hyde

回答

2

argv[0]是程序可執行文件名,它的得計argc

所以./todoargc=1,但argv[1]是NULL,這將導致strcmp()的問題。

argv[argc] ==?

更改您的測試: -

if (argc < 2) 
{ 
    printf("Not enough variables."); 
    return 0; // do this, otherwise we'll plough straight on.. 
} 
+1

其實,我99%確定,'argv [argc]'必須是NULL,所以它*被定義。 。:) – hyde

+1

@hyde是正確的,但將支票更改爲'argc <2'仍然不夠。請參閱@ KenWayneVanderLinde的答案。 –

0

您要關閉文件句柄,然後仍然在試圖寫它:

if (...) { 
    fclose(...); <--potentially closing it, depending on the if() results 
} 
fprintf(...); <--potentially writing to a closed handle. 

這是一個壞主意。

+0

fprint,對不起。無論哪種方式...寫封閉的句柄。 –

+0

不應該寫入關閉的'FILE *'只是因爲錯誤而乾脆失敗?所以不是一個壞主意(如UB),只是有點毫無意義/愚蠢(特別是沒有檢查寫錯誤)。但我沒有檢查文檔,所以我想它可能是UB或其他東西,這就是爲什麼我問。 – hyde

+3

'break'可以防止寫入到關閉的句柄,但如果文件打開失敗(導致'f == NULL'),則仍然可能會崩潰。 –

1

正如其他人指出的,您需要argc < 2而不是argc < 1

此外,你可能想從if返回,以停止執行,其餘:

if(argc < 2) { 
    printf("Not enough variables."); 
    return /* some appropriate value here */; 
} 
+0

+1 - 但'可能'?我認爲'絕對',因爲'if'後面的代碼開始訪問'argv'數組。 –

+0

@MichaelBurr:你是對的,我可以(相當)自信地刪除「可能」。然後再次,其他的行動過程是可能的(例如一些默認行爲)。就目前而言,他的代碼沒有考慮到這一點,但他最終選擇的是他的選擇。 –

相關問題