2016-12-07 134 views
1

我想定義一個全局指針變量,然後可以在主函數中真正設置,如下所示。不過,在我嘗試在此之後使用outputName時,我收到了分段錯誤。我知道它可能與在開始時將指針設置爲等於NULL有關...如何獲得一個全局指針然後設置在main中的任何幫助將非常有幫助!這裏是我的代碼是給我的錯誤的部分:全局指針的分割錯誤

char* outputName=NULL; 

int isNumber(char number[]){ 
int i; 
if (number[0]=='-'){ 
    i=1; 
} 
while(number[i] != '\0'){ 
    if (!isdigit(number[i])){ 
    return 0; 
    } 
    i++; 
} 
return 1; 
} 

void catcher(int signo) { 
printf("The program is exiting early"); 
remove(outputName); 
exit(1); 
} 

int main(int argc, char *argv[]) { 
if (argc != 4){ 
    fprintf(stderr,"Incorrect number of arguments, must supply three.\n"); 
    exit(1); 
} 
char* inputName = argv[1]; 
outputName=argv[2]; 
signal(SIGINT, catcher); 
int result=isNumber(argv[3]); 
if (result==0){ 
    fprintf(stderr, "Invalid maximum line length, please enter an integer\n"); 
    exit(1); 
} 
int maxChars= (atoi(argv[3]))+1; 
if ((maxChars-1)<1){ 
    fprintf(stderr, "Invalid third maximum line length, please enter an integer greater than zero\           
.\n"); 
    exit(1); 
} 
FILE* inFile = fopen(inputName, "r"); 
if (inFile==NULL){ 
    fprintf(stderr,"Error while opening %s.\n", inputName); 
    exit(1); 
} 
FILE* outFile= fopen(outputName, "w"); 
if (outFile==NULL){ 
    fprintf(stderr,"Error while opening %s.\n", outputName); 
    exit(1); 
}                        
char line[maxChars]; 
int done=0; 
while (!done){ 
    char *readLine=fgets(line,maxChars,inFile); 
    if (readLine==NULL){ 
    if (errno==0){ 
     done=1; 
    } 
    else{ 
    fprintf(stderr, "Error when reading line from input file"); 
    exit(1); 
    } 
} 
int len=strlen(line); 
if (line[len-1]!='\n'){ 
    line[len]='\n'; 
    line[len+1]='\0'; 
    char current=' '; 
    while (current != '\n'){ 
    current=getc(inFile); 
    } 
} 
if (!done){ 
    fputs(line, outFile); 
    if (errno!=0){ 
    fprintf(stderr, "Error when writing line to output file"); 
    exit(1); 
    } 
    } 
} 
return 0; 
} 
+0

你傳遞給'main()'多少個參數?你有沒有做過基本的調試,看看'argv [2]'的價值是什麼?你是否檢查過'argc> = 3'? – John3136

+0

傳遞四個參數,是做了所有錯誤檢查,以確保are的值是正確的。 – liverr1818

+1

所以如果'outputName'在上面的代碼之後是有效的,那麼問題就在別的地方...... – John3136

回答

3

可能是信號處理函數獲取調用之前outputName越來越設置爲非空值,你可以嘗試後outputName = argv的設置信號處理程序[2] ;在main()

2

閱讀仔細signal(7):因爲你的catcher電話printf這不是一個異步信號安全功能,您的代碼undefined behavior。此外,您的printf控制字符串不會以\n結尾,並且由於標準輸出是行緩衝的,因此不會執行輸出。首選sigaction(2)signal,並在之後安裝信號處理程序,該信號處理程序已分配outputName

信號處理程序中使用的全局變量應聲明爲volatile。因此請在全球範圍申報您的char* volatile outputName;。然後你可以在處理程序中進行像if (outputName != NULL) remove(outputName);這樣的測試。通常的做法是在信號處理程序中設置一些volatile sig_atomic_t全局標誌,並在其他地方測試該標誌。

而你的程序很可能沒有時間得到任何信號。您可能應該等待一段時間(例如從stdinusleep(3)pause(2)poll(2) ....)讀取main函數。

當然,使用調試器(gdb)編譯您的代碼,並帶有所有警告和調試信息(gcc -Wall -g)和;我想調試器watchpoints應該是非常有用的找到你的錯誤。

您顯示的程序很可能不會顯示任何SEGV。所以你的實際錯誤很可能是其他地方。

也許使用strace(1)和/或valgrind也可以幫助。