0

我目前正在编写一个 shell,它获取输入并将其存储在字符串 (char*) 数组中。为了启用像流水线这样的 UNIX 操作,我希望能够编写类似的命令

echo this | function more | function2

为此,我在 while 循环中收集命令及其参数,并尝试将参数数组的所有内容复制到一个新的二维数组中,该数组包含整个命令行,例如“ ls -f -a”。到目前为止,这是可行的,但是,一旦|在命令行中找到“”,我就会尝试重置循环,忽略“ |”,并开始一个新的循环做同样的事情,直到'\0'找到,这标志着原始输入的结尾:

char* arguments[MAXARGS]; // holds argument components, e.g. "ls" or "-f"
char** arg_collection[MAXARGS][MAXARGS]; // supposed to hold command lines, e.g. "ls -f -a"
argc_current = 0; // iterator for the loop, counts arguments
col_iterator = 0; // iterator for amount of command lines
int sentinel = 1; // sentinel value for while loop
...

while(sentinel)
{
    arguments[argc_current] = (char*) malloc (sizeof(word)); // word is defined, just not listed on here - refers to the currently read command / argument
     strcpy(arguments[argc_current], word); // copy current word into arguments

    if(tokens[argc_current] == TOKEN_TERMINATOR || tokens[argc_curernt] == TOKEN_NULL)
    {
       sentinel = 0; // tokens holds information about the type of word, e.g. if it is '\0'
    }

    if(tokens[argc_current] == T_BAR) // if the word is "|"
    {
       for(i = 0; i < argc_current; i++)
       {
          strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection
       }

       col_iterator++; // increment command line counter
       argc_current = 0; // reset argument counter, restart the loop
    }

    else
    {
        arg_current++; // increment current argument counter
    }
}

evaluating arguments here..

第一个循环工作正常,例如,如果我输入

echo this | echo more |

它填充arg_collection[0][0]and arg_collection[0][1],所以我得到 " echo this" 结果。然而,在col_iterator增加到 1 之后,当我注意到第二个“|”时调用 strcpy 时,我以分段错误的形式撞到了砖墙。为什么?

4

2 回答 2

2

看起来word是一个char*. 如果是这样,你应该改变

arguments[argc_current] = (char*) malloc (sizeof(word));

arguments[argc_current] = malloc(strlen(word)+1);

sizeof(word)会给你一个指针变量的大小,而不是它指向的数据的大小。 strlen告诉你word. 是终结器所+1必需的。'\0'

于 2013-04-12T15:06:41.487 回答
0

首先,您应该在使用之前分配 arg_collection。(由于您没有提供整个代码,我假设您不这样做)。

然后,您将在线取消引用您的 arg_collection 的两倍:

strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection

当你必须

strcpy(arg_collection[col_iterator], arguments[i]); 

也就是说,当它只是一个字符时,您将 arg_collection 中字符串 col_iterator 的索引 i 处的字符视为 char *。

于 2016-04-22T12:07:35.953 回答