-2

以下のコードは、シェルとして動作するはずです。前と次のオプション、履歴のような機能、終了、実行コマンドがあります。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define HISTORY_LENGTH 128

int executeCommand(char*cmd)
{
    return(!strcmp(cmd,"e\n"));
}

int exitCommand(char*cmd)
{
    return (!strcmp(cmd,"exit\n"));
}

int previousCommand(char*cmd)
{
    return (!strcmp(cmd,"p\n"));
}

int nextCommand(char*cmd)
{
    return (!strcmp(cmd,"n\n"));
}

void execute(char *line)
{
    line[strlen(line)-1]='\0';
    char **arguments;
    char* temp;
    int i=0;
    arguments=(char**)malloc(sizeof(char)*10);
    temp=strtok(line," ");
    arguments[i]=malloc(strlen(temp)*sizeof(char));
    if(arguments[i]!=NULL)
    {
        strcpy(arguments[i],temp);
        i++;
    }
    else
    {
        printf("Out of memory");
    }
    while(temp!=NULL)
    {
        temp=strtok(NULL," ");
        if(temp==NULL){
            arguments[i]=NULL;
        }
        else{
            arguments[i]=malloc(strlen(temp)*sizeof(char));
            if(arguments[i]!=NULL)
            {
                strcpy(arguments[i],temp);
                i++;
            }
        }
    }
    printf("%s  ",arguments[0]);
    printf("%s  ",arguments[1]);
    printf("%s  ",arguments[2]);
    execvp(arguments[0],arguments);
}

int main(int argc, char*argV[]) {
    int i;
    char *cmd=(char*)malloc(sizeof(char)*BUFFER_SIZE);
    char **history=NULL;
    int historylength=0;
    int currentCommand=0;
    history=(char**)malloc(sizeof(char)*BUFFER_SIZE);
    do{
        fgets(cmd,BUFFER_SIZE-1,stdin);
        if(exitCommand(cmd))
            break;
        else
            if(previousCommand(cmd))
            {
                if(currentCommand>0)
                    printf("%s",history[--currentCommand]);
                else if(currentCommand==0)
                {
                    currentCommand=historylength;
                    printf("%s",history[--currentCommand]);
                }
            }
            else
                if(nextCommand(cmd))
                {
                    if(currentCommand<historylength)
                        printf("%s",history[currentCommand++]);
                }
                else
                    if(executeCommand(cmd))
                    {
                        execute(history[--currentCommand]);
                    }
                    else
                    {
                        history[historylength]=malloc(strlen(cmd)*sizeof(char));
                        if(history[historylength]!=NULL)
                        {
                            strcpy(history[historylength],cmd);
                            currentCommand=++historylength;
                        }
                        else
                        {
                            printf("Out of memory");
                            break;
                        }
                    }

    } while(1);

    free(cmd);

    for(i=0;i<historylength;i++)
        free(history[i]);
    free(history);

    return 0;
}

関数 cat でこれを機能させたいと思います。e cat main.c と入力し、cat コマンドを実行することを期待していますが、何もしていません。ここで何が間違っているのでしょうか? 私はこれのプロではないので、すべての助けに感謝します。

4

1 に答える 1

3

これは正しくありません:

arguments=(char**)malloc(sizeof(char)*10);

argumentsであるchar**ため、コードは を割り当てる必要がありますsizeof(char*)。への変更:

arguments = malloc(10 * sizeof(*arguments));

も同じ間違いですhistory。さらに、「malloc の結果をキャストしますか?」を参照してください。

終了ヌル文字を書き込む際に必要な数よりも1 つchar少なく割り当てられます。変化する:char*strcpy()

arguments[i]=malloc(strlen(temp)*sizeof(char));

に:

arguments[i] = malloc(strlen(temp) + 1);

sizeof(char)であることが保証されて1おり、サイズ計算から省略できます。

iに割り当てられたメモリの境界を超えないようにしますarguments。コードが現状のままであるためi、超えないようにするための保護はありません9( 0toは、割り当てられた要素9の有効な値です)。iarguments10

于 2012-12-10T21:44:15.460 に答える