我正在编写一个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]
和arg_collection[0][1]
,因此我会收到“echo this
”。
然而,在将col_iterator
增加到1之后,在注意到第二个“|”时调用strcpy时,我以分段错误的形式撞到了一堵砖墙。为什么呢?
答案 0 :(得分:2)
看起来word
是char*
。如果是这样,你应该改变
arguments[argc_current] = (char*) malloc (sizeof(word));
到
arguments[argc_current] = malloc(strlen(word)+1);
sizeof(word)
将为您提供指针变量的大小,而不是它指向的数据的大小。 strlen
会告诉您word
中的字符数。 +1
终结符需要'\0'
。
答案 1 :(得分: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视为char *。