【发布时间】:2015-09-29 12:40:37
【问题描述】:
我正在用 C 实现一个 shell,但在解析命令行条目时遇到了一些问题。我希望我的解析器方法能够分隔由空格字符分隔的命令行条目,并将结果作为双字符指针返回。即,假设我有“ls -l >ls.txt”,我的解析器应该返回一个带有 r[0]="ls"、r[1]="-l" 和 r[2]= 的 char **r ">ls.txt"。
这是我当前的解析方法的代码,顺便说一下,是段错误,我不知道如何解决这个问题:
char **parser(int *argc, char *s)
{
char **r;
char *t, *m;
int i,n,size;
t = malloc(strlen(s)); // firs i used this instead of *r, but i run
// into trouble when i have more than two
// argc. ( You see why, right?)
//strcpy(t,s);
i = 0;
size = 5;
r = malloc(size*sizeof(char *));
while (( m = strchr(s, ' '))) {
n = ((int)m) - ((int)s);
if (i==0) {
*r = malloc(n);
} else {
*r = realloc(*r, n);
}
strncpy(*r, s, n);
*r[n]= '\0';
s = (char*)(s+n+1);
if (i == size)
r = realloc(r, (size = 2*size)*sizeof(char*));
i++;
r = (char **)(r + sizeof(char*));
}
s[strlen(s)-1] = '\0';
if ((i<1) || (strlen(s)>1)) {
*r = s;
}
*argcp = ++i;
return r;
}
我知道我的代码并不理想。使用 strsep 可以做得更好,但我主要关心的是如何管理我想要返回的双字符指针的内存。
感谢您的帮助!
【问题讨论】:
-
注意,在普通的shell中,你可以写
> file或>file,并且都将标准输出重定向到file。你也可以写ls -l|wc-l或ls -l | wc -l(或者混合'n'match管道符号周围的间距。也就是说,大多数shell对于空白的位置非常灵活。(事实上,>file ls -l发送@的输出987654328@ 到file;ls >file -l也是如此!) -
在演示方面,如果代码有系统的缩进,你的代码会更容易阅读,并且不会沉迷于像
if (...) a = ...;这样的无端技巧都在一行上。它只是让你很难阅读你的代码。如果您需要帮助,您需要确保您的代码易于其他人阅读。 -
n = ((int)m) - ((int)s); if(i==0){ *r = malloc(n); }else{ *r = realloc(*r, n); }的行中有一个麻烦的世界第一行应该是n = (int)(m - s);(或者你可以省略演员表)。malloc()或realloc()在r中的空间应该是char *值的数组(这就是你使用char **r声明它的原因)。分配的空间需要是char *值的个数,大小需要按sizeof(*r)缩放。然后,您对字符串处理的管理不善。是时候重做第一原则了。 -
感谢您的第一条评论!我现在要在解析器中解决这个问题!
-
您需要一个由
char **指向的(不断增长的)char *值数组(因此r可以作为变量定义)。对于数组中的每个条目,您需要一个长度足以容纳字符的字符串加上一个空终止符。该字符串将由r数组中的一个条目指向:r[i] = malloc(strlen(str) + 1);或类似的。或者,更好的是,使用或实现strdup()。
标签: c shell command-line command-line-arguments