c - 获取用户输入并将其分割成一个结构以传回给 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;
}
解决方案
您正在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;
}
推荐阅读
- javascript - 缺少“let”关键字会改变程序流程
- swift - 从 Firebase Storage iOS(swift)获取文件夹名称
- c++ - OpenGL 空项目占用过多 CPU
- java - 线程程序,输入一个输入并停止“hello world”输入并一直输入另一个输入,直到输入“quit”?
- python - 获取图像opencv python中每个通道的对比度
- java - 即使我初始化了适配器,也没有附加适配器跳过布局
- javascript - 从可重用组件发送道具用于导航抽屉
- html - 带有无限动画的css伪元素溢出身体
- laravel - Laravel 从blade.php 将数据插入数据透视表
- html - 如何仅表示月份