c - 在 C 中使用 strtok 解析输入

标签 c parsing strtok execvp

我在一个类中有一个项目需要我在 C 中构建一个简单的 shell。我是 C 的新手,我现在面临的问题是在发送命令执行之前正确解析命令.我知道有几种不同的方法可以做到这一点,但我们需要使用 strtok,我似乎遇到了一些问题。

这是我的全部代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

int parseCommands(char *command, char **args){
    int pos = 0;
    printf("%s\n", command);
    char *readCommand = NULL;
    char delims[] = {" \n"};
    readCommand = strtok(command, delims);
    while(readCommand != '\0'){
        printf("%s\n", readCommand); 
        strcpy(args[pos], readCommand);
        printf("%s\n", args[pos]);
        readCommand = strtok(NULL, delims);
        pos++;
    }
    return pos;
}

int executeCommand(char **args){
    pid_t pID;
    switch(pID = fork()){
        case 0:
            execvp(args[0], args);
            perror("Some sort of exec error");
            return -1;
        case -1:
            perror("Could not even fork");
            return -2;
        default:
            wait(NULL);
            return 0;
    }
}

void main(){

    char wd[256];
    char input[256];
    char *args[15];

    char strDelims[] = ";";
    char *readInput = NULL;

    while(1){

        getcwd(wd, sizeof wd);
        printf("mysh: %s> ", wd);
        fgets(input, sizeof input, stdin);

        readInput = strtok(input, strDelims);

        int numArgs;
        numArgs = parseCommands(readInput, args);
            if(numArgs < 1)
                printf("There was a problem parsing the command\n");

            if(strcmp(args[0], "cd") == 0){
                printf("%d\n", numArgs);
                if(numArgs > 1){
                    if((chdir(args[1])) < 0){
                        perror("I'm afraid I can't let you do that Dave\n");
                    }
                }
                else{
                    if((chdir(getenv("HOME"))) < 0){
                        perror("Can't go home\n");
                    }
                }
            }
            else if(strcmp(readInput, "quit") == 0){
                break;
            }
            else{
                if((executeCommand(args)) != 0)
                    printf("Problem executing the command\n");
            }
            readInput = strtok(input, strDelims);
    }

}

这是几个命令的输出:

mysh: /path/to/stuff> cd
cd

cd
cd
1
mysh: /path/to/home> cd /bin
cd /bin

cd
cd
/bin
/bin
2
mysh: /bin> ls
ls

ls
ls
Segmentation fault
mysh: /path/to/stuff> ps aux
ps aux

ps
ps
aux
aux
Segmentation fault

我只是认为 cd 似乎工作得很好但它并不真正喜欢其他任何东西,这很奇怪。这让我觉得稍后会出现问题(但在 numArgs 的 printf 之前?)。另外仅供引用,我们被告知每个命令不会超过 15 个参数或 256 个字符。

这让我沮丧了一段时间,所以对这个特定问题的任何帮助都会很棒(我意识到那里还有其他错误或代码部分不佳,但我想自己找出/解决这些问题) .多谢! :)

最佳答案

一些建议

通常 strtok 共享一个静态缓冲区,所以当你先调用 strtok 之前 你的解析函数,然后在解析函数中你可能搞砸了 之前缓冲区中有什么。

你也没有为 args[] 分配空间你只声明了一个指针数组 (char *args[15]) 但随后在您的解析函数中,您对指针指向的任何内容执行 strcpy。 您需要分配一个缓冲区,分配给 args[i],然后将字符串复制到它。

所以而不是

strcpy(args[pos], readCommand);

args[pos] = strdup(readCommand);

关于c - 在 C 中使用 strtok 解析输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12681034/

相关文章:

c - 如何知道 int* 数组的结尾?

c++ - 为 Erlang 提取 C 函数签名

C strtok,使用第一个空格将字符串分成两部分

c - 将文件中的字符串拆分为c中的数组

c - 了解 x86 IA32 程序集中函数调用的前/后汇编代码

c - 如何在不改变指针指向地址的情况下改变指针的内容?

c - C 中的文件 IO 和字符串意外值

javascript - 如何在php中解析javascript数组

parsing - 使用秒差距解析命令式语言的奇怪行为

在 Linux 中创建简单的 Shell