C++ 制作简单的unixshell时遇到的问题

C++ 制作简单的unixshell时遇到的问题,c++,shell,C++,Shell,我正在尝试在Unix中创建一个简单的shell。我读了很多书,发现每个人都经常使用strtok函数。但是我不想做任何特殊的功能。所以我写了代码,但我似乎无法让它工作。我做错了什么 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 ;

我正在尝试在Unix中创建一个简单的shell。我读了很多书,发现每个人都经常使用
strtok
函数。但是我不想做任何特殊的功能。所以我写了代码,但我似乎无法让它工作。我做错了什么

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);
}
void过程(char**);
int arg_计数;
字符**拆分命令(字符*输入)
{
字符温度[81][81],*cmdptr[40];
int k,done=0,no=0,arg_count=0;
对于(int i=0;输入[i]!='\0';i++)
{
k=0;
而(1)
{
如果(输入[i]='')
{
arg_count++;
打破
}
如果(输入[i]='\0')
{
arg_count++;
完成=1;
打破
}
temp[arg_count][k++]=输入[i++];
}
温度[arg_count][k++]='\0';
如果(完成==1)
{
打破
}
}

对于(int i=0;istrtok并不是一个真正的特殊函数,因为它是标准include string.h中的标准函数,所以没有理由不使用它。

strtok并不是一个真正的特殊函数,因为它是标准include string.h中的标准函数,所以没有理由不使用它。

如果您决定使shell更加复杂然后你可以考虑使用一个工具进行词汇分析

例如:


如果您决定让shell更复杂,那么您可能会考虑使用一个工具进行词法分析

例如:

有几件事:

  • 您不会从
    splitcommand
    函数返回任何内容
  • splitcommand
    函数中执行的所有操作都是在局部变量中完成的,因此它(尤其是您生成的字符串)将无法在结束后继续执行
  • 附加null终止符的代码错误(您将其放在以下字符串中,而不是当前字符串)
  • 使用固定大小的缓冲区是一个不错的选择;人们喜欢它
  • 请注意,在真正的UNIX shell中,并非每个空格都指定参数,也并非每个参数都由空格指定
我建议您使用字符串和一些(真实的)解析器框架,前提是它对您来说不太特殊。

以下几点:

  • 您不会从
    splitcommand
    函数返回任何内容
  • splitcommand
    函数中执行的所有操作都是在局部变量中完成的,因此它(尤其是您生成的字符串)将无法在结束后继续执行
  • 附加null终止符的代码错误(您将其放在以下字符串中,而不是当前字符串)
  • 使用固定大小的缓冲区是一个不错的选择;人们喜欢它
  • 请注意,在真正的UNIX shell中,并非每个空格都指定参数,也并非每个参数都由空格指定

我建议您使用字符串和一些(真实的)解析器框架,前提是它对您来说不太特殊。

问题在于

arg_count++;  
if(输入[i]='')和
if(输入[i]='\0')

分析命令行时,如果找到空格或到达命令行末尾,则在读取的命令末尾添加一个
\0
之前,先递增arg\u count

因此,将其更改为:

        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
    因为它们指向本地字符 不会持久化的数组(
    temp
    ) 在函数返回后。因此 必须确保阵列
    temp
    即使在运行后也会持续 通过动态分配或 使之全球化
  • execvp
    的参数对于 我。其他人请看一看

问题在于

arg_count++;  
if(输入[i]='')和
if(输入[i]='\0')

分析命令行时,如果找到空格或到达命令行末尾,则在读取的命令末尾添加一个
\0
之前,先递增arg\u count

因此,将其更改为:

        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
    因为它们指向本地字符 不会持久化的数组(
    temp
    ) 在函数返回后。因此 必须确保阵列
    temp
    即使在运行后也会持续 通过动态分配或 使之全球化
  • execvp
    的参数对于 我。其他人请看一看

这几乎肯定是家庭作业。除非你被告知要避免使用库函数。事实上,很可能你被告知要实现strtok。

这几乎肯定是家庭作业。除非你被告知要避免使用库函数。事实上,很可能你被告知要实现strtok。

不,先生,我只是想让这个工作。我不理解这个代码的问题。你能帮忙吗?不,先生,我只是想让这个工作。我不理解这个代码的问题。你能帮忙吗?谢谢你,先生:)。但是我不必在splitcommand()中返回任何内容.Do I?我所做的就是通过传递cmdptr从split命令调用进程。空值怎么会成为问题?它本身就是同一个字符串rt?arg_计数在那里没有变化?只有k?我使用它并将命令分隔开。也就是说,如果我给ls-l,我将得到cmdptr[0]=ls和cmdptr[1]=-l.但是我的execvp不工作。传递给exec的参数是否正确?谢谢,先生:)。但是我不必在splitcommand()中返回任何内容.Do I?我所做的就是通过传递cmdptr从split命令调用进程。空值怎么会成为问题?它本身就是同一个字符串rt?arg_计数在那里没有变化?只有k?我使用它,并将命令分隔开。如果我给ls