C++ 制作简单的unixshell时遇到的问题
我正在尝试在Unix中创建一个简单的shell。我读了很多书,发现每个人都经常使用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 ;
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