我正在创建一个程序,使用execvp
函数执行用户输入的bash命令。在执行每个命令后,它应该接受另一个命令并执行该命令。例如:
bash$ ./prog ls -l
-rw-r--r--. 1 (info-placeholder) file1.txt
ls -l
-rw-r--r--. 1 (info-placeholder) file1.txt
为此,我需要能够将每个用户输入解析为char**
,因为这是execvp
函数:execvp(const char *file, char *const argv[]);
因此,我创建了这个函数来解析用户的输入,并将其放入一个动态分配的char**
,称为arg_list
,其中buff
是程序读取的缓冲区,bytes
是read
函数读取的字节数。
void parse_input(char **arg_list, char *buff, int bytes) {
char *word = malloc(128);
int num_spaces = 0;
for (int i = 0; i < bytes; i++) {
if (buff[i] == ' ') {
num_spaces++;
} // if
} // for
arg_list = malloc((num_spaces) * sizeof(char *));
for (int i = 0, j = 0; i < bytes; i++) {
if (buff[i] != ' ' && buff[i] != (char) 0) {
word[i] = buff[i];
} else {
word[i] = '\0';
arg_list[j] = word;
j++;
free(word);
word = malloc(128);
} // else
} // for
free(word);
} // parse_input
将ls -l
作为用户输入进行测试后,发现word
在添加到arg_list
后没有被重置。我不确定还可以如何将用户输入的单词添加到列表中,以及为什么word
没有被重置。
编辑:我现在意识到我的代码中有多少错误,而且可能还有更多的错误,对不起。为了简短起见,我已经尝试根据你们的更正来修复我的代码,但我仍然不能让它工作。下面是:
void pars_input(char ***arg_list, char *buff, int bytes) {
printf("Beginning to parse user input\n");
int num_spaces = 0;
bool is_white_space = true;
for (int i = 0; i < bytes; i++) {
if (is_white_space && !isspace(buff[i])) {
num_spaces++;
is_white_space = false;
} else if (!is_white_space && isspace(buff[i])) {
is_white_space = true;
} // else if
} // for
printf("Number of words: %d\n", num_spaces);
(*arg_list) = malloc((num_spaces + 1) * sizeof(char *));
is_white_space = true;
for (int i = 0, j = 0, k = 0; i < bytes; i++) {
if (is_white_space && !isspace(buff[j])) {
(*arg_list)[j][k] = '\0';
printf("Word added: %s\n", (*arg_list)[j]);
j++;
k = 0;
} // if
else if (!is_white_space && isspace(buff[i])) {
is_white_space = true;
(*arg_list)[j][k] = buff[i];
k++;
} // else if
} // for
} // parse_input
如果没有一个临时单词来添加buff
中的字符,我就无法知道如何将该单词添加到动态分配的arg_list
中。
1条答案
按热度按时间dvtswwa31#
问题很多。
word
指向的内存。它也被arg_list[ j ]
指向,你仍然在使用它。删除第一个free(word);
。arg_list
中。word[i] = buff[i];
显然对除第一个单词以外的任何单词都是错误的。如果输入以空格开头,它对第一个单词也是错误的。num_spaces
元素,但可能还有一个以上的元素。例如,a b c
有两个空格,但有三个单词。arg_list
作为参数,但在未使用它的情况下替换了它的值。arg_list
对调用者没有影响,因为C是按值传递的。arg_list
给调用者是不够的。调用者还需要知道数组中有多少个元素。例如,这可以通过添加一个额外的元素NULL
来实现,就像exec*
所期望的那样。