我正在写一个简单的shell。我编写了一个解析器来标记命令行以将其发送到execvp
。我想在解析时检查字符&
并将其替换为\0
。我正在使用指针,并对如何继续进行略微混淆。这是我的解析器代码:
void parseArgs(char *input, char **args, int *background)
{
while (*input != '\0') {
while (*input == ' ' || *input == '\t' || *input == '\n')
*input++ = '\0'; /* replace empty spaces */
*args++ = input; /* save argument position */
while (*input != '\0' && *input != ' ' &&
*input != '\t' && *input != '\n')
input++; /* read argument until next empty space */
}
*args = NULL; /* end of the argument list */
}
由于我正在使用指针,我在替换我想要的东西时遇到了困难。我应该使用相当于上面的数组,还是有一个简单的解决方案?基本上,如果读取background
,我希望我的代码将1
切换为&
,然后将此字符替换为\0
。有没有办法只使用指针替换字符?
答案 0 :(得分:0)
尽管我的评论重新strtok
你的解析器并不是一个糟糕的尝试。请注意,它不会检查您是否超出**args
的结尾。
您的部分问题是您的问题没有明确定义。您想检查上一个参数的最后一个字符是&
吗? (如果是这样,在参数处理结束时,修复它)。或者你想将&
计为终止分隔符,并将之前的所有内容计为一个命令,之后的所有内容都计为另一个命令?在这种情况下,最好的办法是预处理字符串,将&
替换为\0
,然后调用parseArgs
,运行shell,以及何时你已经完成了,从你到达的地方开始(所以foo & bar & baz
工作)。但是,在真正的shell中,您可以执行2>&1
之类的操作作为I / O重定向。要使这样的工作正常工作,您可能最好进行正确的标记。为此,yacc / lex是你的朋友。
修改 - 在&
执行以下操作之前检查*args = NULL
最后的权限:
int lenlast = strlen (*args);
if ((*args)[lenlast] = '&')
{
(*args)[lenlast] = '\0';
background = 1; /* declare that somewhere */
}