在c中为execvp()标记用户输入

时间:2016-05-17 10:12:31

标签: c unix

fgets(command, BUFFSIZE, stdin);
command[strlen(command)-1] = '\0';

char *p = strtok(command, " ");
char *command_tok[BUFFSIZE];
int i = 0;
while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " ");
}


char *commands[] = {*command_tok, NULL};
execvp(command_tok[0], commands);

我尝试获取用户的输入,将其标记化并将命令和参数存储在数组中以将其传递给execvp()。但是,这些论点永远不会被阅读。如果输入为“ls -l”,则始终以“ls”执行。

3 个答案:

答案 0 :(得分:4)

这一行:

// makes a two element array
char *commands[] = {*command_tok, NULL};

错了。

它创建了一个只包含两个元素的新数组,第一个元素是command_tok [0]。相反,你想要的是

   command_tok[i] = NULL
   execvp(command_tok[0], command_tok);

另外

command[strlen(command)-1] = '\0'

是荒谬的:strlen通过搜索空字节来查找长度,然后再将其设置为null。

这是我的版本:

#include <string.h>
#include <unistd.h>

#include <cstdio>
static const int BUFFSIZE=200;

int main(int argc, char* argv[]) {
  char command[BUFFSIZE] = { 0 };
  fgets(command, BUFFSIZE, stdin);
  // remove trailing new line if present
  commmand[strcspn(command, "\n")] = 0;

  char *p = strtok(command, " ");
  char *command_tok[BUFFSIZE];
  int i = 0;
  while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " ");
  }

  command_tok[i] = NULL;
  execvp(command_tok[0], command_tok);
}

删除尾随新行的单行来自Removing trailing newline character from fgets() input

答案 1 :(得分:1)

在-l之后你没有空格,因此,你的选项将'-l \ n'作为参数。所以你必须使用'\ n'也在strtok函数的分隔符中。

以下代码将按预期工作。

fgets(command, BUFFSIZE, stdin);
command[strlen(command)-1] = '\0';

char *p = strtok(command, " \n");
char *command_tok[BUFFSIZE];
int i = 0;
while (p) {
    command_tok[i++] = p;
    p = strtok(NULL, " \n");
}
command_tok[i] = NULL;

execvp(command_tok[0], command_tok);

使用fgets读取输入时,如果它不是EOF,则最后有\ n。所以,使用它你可以选择参数。

答案 2 :(得分:0)

您向commands提供了一个完全由两个元素组成的数组:(第一个)元素command_tok指向,NULL。编译器应该如何知道你是指数组command_tok的所有元素,以及它应该如何确定它的大小?