1

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 文字を超えないように言われました。

これはしばらくの間私を苛立たせていたので、この特定の問題の助けがあれば素晴らしいでしょう (そこには他のエラーやコードの不十分なセクションがあることに気づきましたが、自分でそれらを見つけ出し/修正したいと思います)。どうもありがとう!:)

4

1 に答える 1

3

いくつかのポインタ

通常、strtokは静的バッファーを共有するため、最初に解析関数の前にstrtokを呼び出し、次に解析関数内で呼び出すと、おそらく前にバッファーにあったものを台無しにします。

また、args []にスペースを割り当てず、ポインターの配列を宣言するだけです(char *args[15]) が、解析関数では、ポインターが指すものすべてにstrcpyを実行します。バッファを割り当て、args [i]に割り当ててから、文字列をそこにコピーする必要があります。

だから代わりに

strcpy(args[pos], readCommand);

行う

args[pos] = strdup(readCommand);
于 2012-10-01T21:11:35.430 に答える