2015-02-04 11 views
-1

셸을 만들려고하는데 내가 찾고있는 조건 중 하나는 사용자가 공백을 입력 할 때입니다. 그러나 터미널에 공백을 입력 할 때 fgets에서 segfault를 얻습니다. 그것은 하나의 공간이 될 수도 있고, 무작위적인 문자가 뒤따라 오는 한 무리 일 수도 있습니다. 나는 segfault를 계속 얻는다.fgets는 공백 만 전달할 때 segfault를 제공합니다.

개발 : 토큰 기능을 제거하면 segfault가 표시되지 않습니다. 왜 이것이 사실입니까? - NULL 포인터

입력이 공백 문자로 시작
/*Split the line into tokens*/ 
if(input[0] != ' ') 
    tokens = tokenize(tokenized); 

/*if tokens[0] == 'exit', then quit. 
*/ 

if(strcmp(*(tokens),"exit") == 0){ 
    break;} 

, 당신은 역 참조 tokens에 토큰 화 기능과 시도를 건너 : 여기에 문제가있어

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


/* Initialize variables and methods */ 

int status; 
int i; 
int one_nonspace = -1; 
int on = 1; 
char input[101]; 
char temp[101]; 
char* tokenized; 
char operators[3] = {'>', '<', '|'}; 
char** tokens; 



void getInput(char *prmpt, char *buff){ 

    printf(">:"); 
    fgets(buff, 101, stdin); //segfault here when input spaces. 

    /*printf("works!");*/ 

    if(one_nonspace != -1){ 
     printf("spaces"); 

     memcpy(temp, &buff[i], (101-i)); 
     temp[100] = '\0'; 


    } 


    if(buff[strlen(buff) -1] != '\n'){ 
     int over = 0; 

     while(fgetc(stdin) != '\n') 
      over++; 

     if(over>0) 
     { 
      printf("Command is over 100 characters. Please try again\n"); 
      status = 1; 
     } 
    } 

    else{ 
     buff[strlen(buff) - 1] = '\0'; 
     status = 0; 
    } 



} 


char** tokenize(char* a_str) 
{ 
    char** result = 0; 
    size_t count  = 0; 
    char* tmp  = a_str; 
    char* last = 0; 
    char delim[2]; 
    delim[0] = ' '; 
    delim[1] = 0; 

    /* Count how many elements will be extracted. */ 
    while (*tmp) 
    { 
     if (' ' == *tmp) 
     { 
      count++; 
      last = tmp; 
     } 
     tmp++; 
    } 

    /* Add space for trailing token. */ 
    count += last < (a_str + strlen(a_str) - 1); 

    /* Add space for terminating null string so caller 
     knows where the list of returned strings ends. */ 
    count++; 

    result = malloc(sizeof(char*) * count); 

    if (result) 
    { 
     size_t idx = 0; 
     char* token = strtok(a_str, delim); 

     while (token) 
     { 
      assert(idx < count); 
      *(result + idx++) = strdup(token); 
      token = strtok(0, delim); 
     } 
     assert(idx == count - 1); 
     *(result + idx) = 0; 
    } 

    return result; 
} 



/* Create a parser Feb 2*/ 


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

    while(on){ 

     getInput(">: ", input); 
     tokenized = input; 



     if(status == 0){ 
      /*printf("%s\n", input);*/ 

     } 




     /*Split the line into tokens*/ 
     if(input[0] != ' ') 
     tokens = tokenize(tokenized); 

     /*if tokens[0] == 'exit', then quit. 
     */ 

     if(strcmp(*(tokens),"exit") == 0){ 
     break;} 


    /*2/3 Now we need to do something with the split up tokens*/ 
     /*printf("input after token: %s\n", input);*/ 
    /*Free the tokens at the end!!! Remember this!*/ 
     if (tokens) 
     { 
     int i; 
     for (i = 0; *(tokens + i); i++) 
     { 
      printf("%s\n", *(tokens + i)); 
      free(*(tokens + i)); 
     } 

     free(tokens); 
     } 
    } 


    return 0; 




} 
+1

나를 위해 충돌하지 않습니다. 어떤 플랫폼을 사용하고 계십니까? 충돌을 일으킬 수있는 최소 입력은 무엇입니까? 이 코드가 정확한 코드인가요? –

+0

여기에 충돌이 없습니다. 이것은 정확한 충돌 코드입니까? 이 코드가 충돌합니까? – sonologico

+0

아니요, 내 전체 코드가 아닙니다. 나는 필자가 생각하지 않은 것들을 제거했다. 코드가 모두 편집되도록 코드를 다시 수정하겠습니다. 죄송합니다. 업데이트 : 코드가 모두 지금 있습니다! – Tai

답변

1

:

여기 내 코드입니다.

편집 : 인쇄 문을 사용하여 디버깅하려하지만 유효한 방법이지만 버퍼를 플러시해야합니다. 그렇지 않으면 어떤 결과가 나오기 전에 문제가 발생한 경우 정확한 원인을 알 수 없습니다. fflush으로 명시 적으로 플러시하거나 터미널에있는 경우 줄 바꿈 문자를 사용할 수 있습니다. 대개 줄 바꿈이 적용되기 때문입니다.

+0

명시 적으로 'NULL'로 초기화하면 더 좋을 것이라고 생각하지만,이 경우 절대적으로 필요하지는 않습니다. 정적 지속 기간이있는 초기화되지 않은 변수는 0부터 시작합니다. – sonologico

+0

감사합니다. 저는 여러분이 여러분의 변수를 전역 적 범위 에서조차 '정적'으로 선언해야한다고 생각했습니다. 여기 다른 질문에 대한 독서를하고있는 중, 나는 그렇지 않다는 것을 알게되었습니다. – yellowantphil