c - 获取用户输入并将其分割成一个结构,以便传回给 execvp

标签 c linux

所以我想做的基本上是获取用户输入。用户输入的命令可能类似于 command arg1 arg2 arg3。所以我做了一个结构来保存基本命令 command 和一个指向 char 指针的参数指针来保存参数 arg1 arg2 arg3 以及一个计数来保存参数计数。

在 main 中,我使用 fgets 获取用户输入,然后将其接收并传递给我的 splitCommand 函数。 splitCommand 函数采用 char*,这是带有 args 的完整命令。然后它使用 strtok 将其切碎并将其存储到一个结构中,并将该结构传递回 main。

我遇到的问题是,当我运行它时,如果我键入 command arg1 arg2,它会打印出 command arg1 (null)。所以我不知道我是否只是感到困惑并且错误地引用了结构的参数部分,或者我是否没有将参数正确地复制到结构中。

任何帮助或指出我做错了什么的正确方向将不胜感激。

先谢谢你。

struct Command
{
  char *base;
  char **arguments; //array of pointers
  int count;
};

//Takes a commands string and splits by spaces, returning a string array, including command
struct Command splitCommand(char *cmd)
{
  char *cmdArgs[MAXARGS];

  char *cmd_token = strtok(cmd, " "); //set pointer to first space
  cmd_token = strtok(NULL, " ");      //Chop off first command
  char *cmdFirst = strtok(cmd, " ");  //First command
  int totalArgs = 0;                  //argument counter
  struct Command retCommand;          //command struct
  retCommand.base = cmdFirst;

  //Loop through and get all args
  for (int i = 0; i < MAXARGS; i++)
  {
    if (cmd_token != NULL)
    {
      totalArgs++;
      cmdArgs[i] = cmd_token;
      cmd_token = strtok(NULL, " ");
    }
  }

  retCommand.arguments = cmdArgs;
  retCommand.count = totalArgs;
  return retCommand;
}

//MAIN
int main(int argc, char const *argv[])
{
  //String Array and memory allocation
  char *userCommands[MAXCMDS];
  for (int i = 0; i < MAXCMDS; i++)
  {
    userCommands[i] = malloc(MAXIN);
  }

  //Command 1
  printf("Welcome to MASH!\nmash-1>");
  fgets(userCommands[0], MAXIN, stdin);
  struct Command cmd1 = splitCommand(userCommands[0]);
  printf("%s ", cmd1.base);
  printf("%s ", cmd1.arguments[0]);
  printf("%s ", cmd1.arguments[1]);
  return 0;
}

最佳答案

您以非预期的方式使用了 strtok。您必须使用 cmdString 对其第一个参数调用一次以获取第一个标记,然后使用 NULL 进行所有后续调用以获取其余标记。

此外,您的代码无法编译。发布到 SO 时,您应该始终提供至少可以无错编译的代码。

这是您的代码,经过修改后可以按照(我认为)您的预期工作。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXARGS 256
#define MAXIN 4096

struct Command {
  char *cmdLine; // copy of command line; base and arguments point here
  char *base;
  char **arguments; 
  int argCount;
};

struct Command parseCommand(char *cmdLine)
{
  char *cmdArgs[MAXARGS];
  struct Command cmd;
  cmd.cmdLine = strdup(cmdLine); 
  cmd.base = strtok(cmd.cmdLine, " ");
  cmd.argCount = 0;
  for (char *arg = strtok(NULL, " "); arg; arg = strtok(NULL, " "))
    cmdArgs[cmd.argCount++] = arg;
  cmd.arguments = malloc(cmd.argCount * sizeof *cmd.arguments);
  memcpy(cmd.arguments, cmdArgs, cmd.argCount * sizeof *cmd.arguments);
  return cmd;
}

int main(int argc, char const *argv[])
{
  char buf[MAXIN];
  printf("Welcome to MASH!\nmash-1>");
  fgets(buf, MAXIN, stdin);
  struct Command cmd = parseCommand(buf);
  printf("Command (%d args): %s", cmd.argCount, cmd.base);
  for (int i = 0; i < cmd.argCount; ++i) printf(" %s", cmd.arguments[i]);
  printf("\n");
  return 0;
}

关于c - 获取用户输入并将其分割成一个结构,以便传回给 execvp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52752521/

相关文章:

C++ 引用和 C 指针

c - fgets() 在输入时创建另一个字符串副本?

linux - 从 Pyramid 中杀死 pserve(Gunicorn) 特定服务器

linux - 设备的内存映射 IO 地址是否映射到进程的内核空间?

linux - 如何单独运行 linux/x86/shell_bind_tcp 负载?

linux - 在 mmap 相同文件后删除 tmpfs(/dev/shm) 中的文件

c - 结构指针兼容性

c - 通过执行整数加法在未排序的整数数组中查找目标值

c++ - 使用 Cygwin 编译 Corkscrew 时出现配置错误

linux - 如何通知 GCC 不使用特定寄存器