2012-09-11 175 views
0

對不起,所有的問題,但我運行此代碼時,我的終端窗口上出現「分段錯誤(核心轉儲)」。C分割錯誤

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

static int usage (void) { 
    printf("Usage: head <file>\n"); 
    printf(" Or: head <file> -n <number of characters>\n"); 
    printf(" Or: head -n <number of characters> <file>\n"); 
    return -1; 
} 

int main (int argc,char **argv) { 
    if ((argc != 2) && (argc != 4)) return usage(); 

    char *fileName = argv[1]; 
    int lineCount = 10; 
    FILE *src; 

    if ((argc == 4) && (strcmp(argv[1], "-n" != 0))){ 
     fileName = argv[1]; 
     lineCount = argv[3]; 
     puts("-n in last position"); 
    }else{ 
     fileName = argv[3]; 
     lineCount = argv[1]; 
     puts("-n in first position"); 
    } 

    if((src = fopen(fileName, "r")) == NULL){ 
     puts("Can't open input file."); 
     exit(-1); 
    } 
} 

我非常確定這是與fopen函數,但我不完全確定爲什麼會發生這種情況。

+0

另外我不知道爲什麼在這個格式的代碼非常可怕,所以很抱歉。 –

+0

代碼格式化:避免使用製表符並預先格式化代碼,將製表符設置爲4位,以實現SO上最舒適的格式。 ('pr -e4 -l1 -t'是Linux上的一個合適的命令;可能還有其他的) –

+1

您需要使用'atoi()'或類似的東西來轉換數字參數字符串 - 而不是分配一個指向整數。注意你的編譯器的警告! –

回答

6

它看起來像argc == 2你立即訪問argv [3]。這很受傷。

+1

我認爲這是導致分段錯誤。但一個完整的答案應該包括@AndrianCornish發現的問題 –

+0

你是對的 - 這絕對是未定義的行爲。在實踐中,你會經常發現'argv [argc + 1]'是第一個環境變量,但你當然不能依賴於可移植代碼。 –

5

有幾件事情錯了第一關 - 比較是在函數內部

strcmp(argv[1], "-n" != 0) 

要指定一個字符*爲INT

lineCount = argv[3]; 

這裏

lineCount = argv[1]; 

這裏是我得到的編譯錯誤

[[email protected] ~]$ gcc -Wall -ansi -pedantic uu.c 
uu.c: In function ‘main’: 
uu.c:15: warning: ISO C90 forbids mixed declarations and code 
uu.c:19: warning: passing argument 2 of ‘strcmp’ makes pointer from integer without a cast 
/usr/include/string.h:143: note: expected ‘const char *’ but argument is of type ‘int’ 
uu.c:21: warning: assignment makes integer from pointer without a cast 
uu.c:25: warning: assignment makes integer from pointer without a cast 
uu.c:33: warning: control reaches end of non-void function 
+5

'strcmp(argv [1],「-n」!= 0)'good catch –

+0

不是我 - 它是twas gcc ;-) –

1

你在錯誤的地方在右括號中的一個:

(strcmp (argv[1], "-n" != 0)) 

應該是:

(strcmp (argv[1], "-n") != 0) 

然而,即使一旦這樣固定的,你的論點的處理仍然是不完全正確。

your previous questionhead -n COUNT FILE是不可能的,這使得論證檢查合理簡單。

這裏有您需要現在跟着你允許「浮動」 -n count部分的邏輯:

int linecount 
char *filename = NULL 

if argc == 2: 
    linecount = 10 
    filename = argv[1] 
else: 
    if argc == 4: 
     if argv[1] == "-n": 
      linecount = argv[2] 
      filename = argv[3] 
     else: 
      if argv[2] == "-n": 
       linecount = argv[3] 
       filename = argv[1] 

if filename = NULL: 
    generate some error 

它基本上是第一個抓住了兩個參數的版本。如果它是一個四參數版本,那麼它會找出「-n」的位置,從而可以智能地確定哪個參數是哪個值。你可以看到,這不是你所擁有的(你的代碼在argv[1]中查找linecount,這是從來沒有的情況)。你應該使用類似這樣的內容作爲指導:

argc argv[0] argv[1] argv[2] argv[3] 
---- ------- ------- ------- ------- 
    2 head  <file> 
    4 head  <file> -n  <count> 
    4 head  -n  <count> <file> 

一旦你指出這一點,應該很容易爲不同情況編寫代碼。

你必須把我的那個僞代碼回到當然C(使用strcmp代替==字符串,並確保您使用atoi/strtol的字符串linecount參數轉換爲整數),但是這是最基本的你應該遵循的流程。

0

您允許使用getopt()函數嗎?在Linux上,getopt()函數將處理-n選項在任何一個位置使用aplomb(除非設置了POSIXLY_CORRECT環境變量)。這將讓生活更容易爲你:

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

int main(int argc, char **argv) 
{ 
    int numLines = 10; 
    char *fileName = 0; 
    int opt; 

    while ((opt = getopt(argc, argv, "n:")) != -1) 
    { 
     switch (opt) 
     { 
     case 'n': 
      numLines = atoi(optarg); /* Could check for positive answer */ 
      break; 
     default: 
      usage(); /* Assuming usage() does not return */ 
      break; 
     } 
    } 

    if (optind != argc - 1) /* Insist on one filename argument */ 
     usage(); 

    fileName = argv[optind]; 

    ...open file and process it... 

    return(0); 
} 

注意,這將是很容易處理的標準輸入,而不是一個文件;當然,循環後的條件需要調整。您還可以輕鬆添加-?-h選項以獲得幫助,等等。