2010-04-01 4 views
0

유닉스에서 간단한 셸을 만들려고합니다. 나는 많은 것을 읽었으며 모두가 strtok 기능을 많이 사용한다는 것을 알게되었습니다. 그러나 나는 특별한 기능없이 그것을하고 싶다. 그래서 코드를 작성했지만 제대로 작동하지 않는 것 같습니다. 여기서 내가 뭘 잘못하고 있니? 표준 string.h을 포함에 표준 기능은, 그래서 그것을 사용하지 않는 좋은 이유가 없기 때문에간단한 유닉스 셸을 만드는 데 문제가 있습니다.

void process(char**); 
int arg_count; 
char **splitcommand(char* input) 
{ 
    char temp[81][81] ,*cmdptr[40]; 
    int k,done=0,no=0,arg_count=0; 
    for(int i=0 ; input[i] != '\0' ; i++) 
    { 
     k=0; 
     while(1) 
     { 
      if(input[i] == ' ') 
      { 
       arg_count++; 
       break; 
      } 
      if(input[i] == '\0') 
      { 
       arg_count++; 
       done = 1; 
       break; 
      } 
      temp[arg_count][k++] = input[i++]; 
     } 
     temp[arg_count][k++] = '\0'; 
     if(done == 1) 
     { 
      break; 
     } 
    } 
    for(int i=0 ; i<arg_count ; i++) 
    { 
     cmdptr[i] = temp[i]; 
     cout<<endl; 
    } 
    cout<<endl; 
} 


void process(char* cmd[]) 
{ 
    int pid = fork(); 
    if (pid < 0) 
    { 
     cout << "Fork Failed" << endl; 
     exit(-1); 
    } 
    else if (pid == 0) 
    { 
     cout<<endl<<"in pid"; 
     execvp(cmd[0], cmd); 
    } 
    else 
    { 
     wait(NULL); 
     cout << "Job's Done" << endl; 
    } 
} 


int main() 
{ 
    cout<<"Welcome to shell !!!!!!!!!!!"<<endl; 
    char input[81]; 
    cin.getline(input,81); 
    splitcommand(input); 
} 

답변

0

문제는 if(input[i] == ' ')if(input[i] == '\0')

내부의

arg_count++; 

함께 당신이 읽고 있던 명령의 마지막에 \0을 넣기 전에.

 if(input[i] == ' ') 
     { 
      // arg_count++; REMOVE THIS. 
      break; 
     } 
     if(input[i] == '\0') 
     { 
      // arg_count++; REMOVE THIS. 
      done = 1; 
      break; 
     } 
     temp[arg_count][k++] = input[i++]; 
    } 
    temp[arg_count][k++] = '\0'; // add null-char at the end. 
    arg_count++; // increment should happen here. 

더 버그 :

그래서으로 변경

  • 을 당신은 splitcommand
  • 에서 아무것도 반환되지 않습니다 그들이 지역의 문자를 가리 키 때문에 당신은 cmdptr 을 반환 할 수 없습니다 0을 유지하지 않을 배열 (temp) 함수가 반환 된 후따라서 은 배열 temp이 함수 을 동적으로 호출하거나 심지어 을 전역으로 지정하여 호출 한 후에도 계속 나타나는지 확인해야합니다.
  • execvp에 대한 인수는 에 잘 맞습니다. 다른 사람은보십시오.
+0

큰 실수였습니다. 그러나 문제는 여전히 지속됩니다. 실은 내 주장이 임원에게 전달 되는가? 나는 cmd [0]과 cmd [1]을 출력 할 때를 의미한다. ls -l 명령을 내리면 cmd [0] = ls 및 cmd [1] = -l이 표시됩니다. 그리고 코드는 exec 함수 바로 전에 작동합니다. 그러나 임원은 일하지 않습니다. 무엇이 문제일까요? 미리 감사드립니다 – yuneek

+0

고맙습니다. 프로그램이 작동했습니다 : 대단히 감사합니다 :) – yuneek

1

strtok를 정말 특별한 기능이 아니다.

+1

답장을 보내 주셔서 감사합니다. 하지만이 코드로 작업하고 싶습니다. 너 나 좀 도와 줄 수있어? – yuneek

1

셸을 더 복잡하게 만들려면 어휘 분석 도구를 사용하는 것이 좋습니다. 예를 들어

:

http://en.wikipedia.org/wiki/Flex_lexical_analyser

+1

선생님, 저는이 일을하고 싶습니다. 나는이 코드로 문제를 이해할 수 없다. 도와 줄 수 있어요? – yuneek

2

몇 가지 : 당신이 splitcommand 기능에서 splitcommand 기능에 당신이 할

  • 모든 것을 아무것도 반환하지 않습니다

    • 는 지역 변수에서 이루어집니다 , 그래서 (당신이 만드는 문자열)은 끝까지 살아남지 못할 것입니다.
    • null 종결자를 첨부하는 코드가 잘못되었습니다 (현재 문자열이 아닌 다음 문자열에 넣음).
    • 고정 크기 버퍼를 사용하는 것이 좋습니다. 사람들이 실제 UNIX 쉘에서이 아닌 모든 공간이 인수를 지정하는 것이
    • 참고 사랑하고, 모든 인수를 공백으로 지정하지

    나는 당신이 제공 한 문자열과 일부 (실제) 파서 프레임 워크를 사용하는 것이 좋습니다 것 그것은 당신에게 너무 특별하지 않습니다. 명령 줄을 구문 분석하고 당신이 공간을 찾거나 당신이 증가 ARG_COUNT있는 명령 줄의 끝에 도달 할 때

  • +0

    고맙습니다. :). 하지만 splitcommand()에서 아무것도 반환하지 않아도됩니다. 나는? 내가하는 모든 일은 cmdptr을 전달하여 split 명령에서 프로세스를 호출하는 것입니다. 그리고 NULL은 어떻게 문제가됩니까? 그것은 동일한 문자열 자체 rt입니까? arg_count가 변경되지 않습니까? k 만입니까? 나는 그것으로 일했고 나는 명령을 분리했다. 내가 ls -l을 주면 cmdptr [0] = ls 및 cmdptr [1] = -l이 표시됩니다. 하지만 내 execvp가 작동하지 않습니다. exec에게 전달 된 인수가 맞지 않습니까? – yuneek

    2

    이것은 거의 숙제입니다. 당신이 말하지 않으면 라이브러리 기능을 피할 이유가 없습니다. 실제로 strtok을 구현하라는 지시를 받았을 가능성이 큽니다.

    관련 문제