为shell程序标记char *

时间:2014-07-09 01:25:19

标签: c char tokenize

我正在制作一个支持用户参数和io重定向的shell程序。我在io重定向方面遇到了麻烦,例如:

$cat < hello > world

首先我将参数保存在char*数组中。我检查第一个字符是<还是>,如果是,我需要删除第一个字符并创建文件描述符。

这就是我正在做的事情。

    char* args[50];//<-- cat <hello and >world are in here
    char* fd[2];
    int fdin, fdout;
    if(args[j][0] == '<'){
        close(fdout);
        strncpy(fd[0], args[j][1]. strlen(args[j])-1);
        fdin = open(fd[0], O_RDONLY);
    }

2 个答案:

答案 0 :(得分:1)

为了简化您的工作,请以某种形式语言开始草拟您的输入,例如:

line : ID+ ( '<' ID | '>' '>'? ID )* ( '|' line )* '\0'

在ID运行的地方,其中每个isAlphaisDigitisSpecial由其他字符分隔(如空格,制表符,&#39;&gt;&#39;, &#39;&lt;&#;;&#39; |&#39;等等。

在解析过程中,将第一部分(ID+)添加到链接列表中更容易,然后将该列表转换为argv-argc对。

其余的是专门处理的(不在链表中,因为它们不一般):

  • 使用&#39;&lt;&#39;进行IO重定向和&#39;&gt;&#39;和&#39;&gt;&gt;&#39 ;;然后
  • 使用&#39; |&#39;。
  • 进行流水线操作

由于语言是递归的(注意( '|' line )*),你的解析器也很容易适用于递归函数(参见?你有一个函数parse当它到达&#39; |&# 39;它要求自己解析其余部分。)

注意:虽然我用BNF符号来表达行语法并不意味着你应该使用一种语言解析lib或编译器(yacc浮现在脑海中)。这种语言过于简单易实现,值得用这些工具带来的所有麻烦。

答案 1 :(得分:0)

我假设您以前从未使用argc的{​​{1}}和argv参数?你不需要创建自己的数组,C已经为你做了。最终得到这个main()数组:

argv

或者:

argv[0] = "cat"
argv[1] = "<"
argv[2] = "hello"
argv[3] = ">"
argv[4] = "world"

或者它的任意组合,具体取决于命令行参数中使用的空格。

然后你可以做这样的事情(从简洁中省略错误处理):

argv[0] = "cat"
argv[1] = "<hello"
argv[2] = ">world"