首页 > 解决方案 > 获取用户输入并将其分割成一个结构以传回给 execvp

问题描述

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

在 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;
}

标签: clinux

解决方案


您正在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;
}

推荐阅读