gpt4 book ai didi

c - 我自己的 C Shell 的历史问题

转载 作者:太空宇宙 更新时间:2023-11-04 03:17:48 25 4
gpt4 key购买 nike

作为一个项目,我必须制作自己的 shell 。我做到了,但我在使用历史记录功能时遇到了一些问题。

这是我的一段代码:

int main(int argc, char* argv[])
{
char saisie[300], cwd[1024];
char* nom = getenv("USER");
char* backup[MAXCMD];
int boucle = 1, n = 0, i, u = 0, b = 0;

for(i = 0; i < MAXCMD; i++)
{
backup[i] = NULL;
}
for(i = 0; i < MAX_INPUT_SZ; i++)
{
saisie[i] = 0;
}
char* cmd[MAXPARAMS]; //MAXPARAMS is 20

while( boucle == 1)
{
printf("%s@sam:~ %s> ", nom, (getcwd(cwd, sizeof(cwd))));
fgets(saisie,MAX_INPUT_SZ,stdin);
printf("\n");
split_input(saisie, cmd);

free(backup[u]);
backup[u] = strdup(saisie);
u = (u + 1) % MAXCMD;

b = switchcmd(cmd,backup,b,u);
start(cmd,b);
b = 0; //débloquage fonction start
}
return 0;
}

我用这个函数打印历史:

int historique(char* backup[], int u)
{
int i = u;
int place = 1;
do
{
if (backup[i])
{
printf("%4d: %s\n", place, backup[i]);
place++;
}
i = (i + 1) % MAXCMD;
} while (i != u);
return 0;
}

B用于在用户输入“cd”或“history”时阻止执行功能(开始),因为它会产生错误。

这是当用户输入“cd”、“history”或“exit”时触发的功能:

int switchcmd(char** cmd,char** backup, int b,int u)

{
int i, n = 3, switch_value = 0;
char* error;
char* listcmd[n];
listcmd[0] = "cd";
listcmd[1] = "exit";
listcmd[2] = "history";

for (i = 0; i < n; ++i)
{
if(strcmp(cmd[0], listcmd[i]) == 0)
{
switch_value = i + 1;
break;
}
}

switch (switch_value)
{
case 1:
chdir(cmd[1]);
b = 1;
error = strerror(errno);
if (*error != 0)
{
printf("sam: %s: %s\n", cmd[0], error);
}
break;

case 2:

printf("Bye bye\n");
exit(0);

case 3:
historique((char**)backup,u);
b = 1;
break;
}
return b;
}

当我执行我的 shell 并连续输入这些命令时,它们起作用了。 °i1

> clear    
> ls -a -l
> ls -a
> cd ..
> man chdir

然后是打印历史的“history”,我有这个:°i2

   1:  clear
2: ls
3: ls
4: cd
5: man
6: history

我想要这个输出,所有参数:°i3

1:  clear
2: ls -a -l
3: ls -a
4: cd ..
5: man chdir
6: history`

我不知道为什么,我也不明白为什么 strdup 没有按应有的方式在备份中复制我的 cmd。

有什么帮助吗?

最佳答案

When the user command is store in ' saisie ', this command is duplicate and split in array of parameters. And I use ' cmd ' in the execution fonction, with execvp.

那就是你的大问题了,cmd具有固定长度 1,如果您使用它来存储 execvp 的命令参数,那么你只能存储一件事:NULL .

你有两个选择:

  1. 使用较大的固定大小,例如 char *cmd[100]你可以在哪里储存到 99 个参数,仅此而已。这是最简单的解决方案,但不灵活足够的。尽管某些系统对您可以争论的数量有限制传递给一个新的进程,我不知道是否对所有系统都有限制, thisthis可能会在那里帮助你。

  2. 动态创建 char 的数组指针取决于命令行。这是更多的工作,但这也是更灵活的解决方案。假如说您的命令行不支持管道 ( | ) 和重定向 ( < , << , > , >> ), 然后 split_input可能看起来像这样:

    char **split_input(const char *cmd)
    {
    if(cmd == NULL)
    return NULL;

    char **argv = NULL, **tmp;

    char *line = strdup(cmd);
    if(line == NULL)
    return NULL;

    const char *delim = " \t\n";

    char *token = strtok(line, delim);
    if(token == NULL)
    {
    free(line);
    return NULL;
    }

    size_t len = 0;

    do {
    char *arg = strdup(token);
    if(arg == NULL)
    {
    free_argv(argv);
    free(line);
    return NULL;
    }

    tmp = realloc(argv, (len + 2) * sizeof *argv);

    if(tmp == NULL)
    {
    free_argv(argv);
    free(line);
    return NULL;
    }

    argv = tmp;
    argv[len++] = arg;
    argv[len] = NULL; // argv must be NULL terminated
    } while(token = strtok(NULL, delim));

    free(line);
    return argv;
    }

    void free_argv(char **argv)
    {
    if(argv == NULL)
    return;

    for(size_t i = 0; argv[i]; ++i)
    free(argv[i]);
    free(argv);
    }

    现在你可以像这样使用它:

    while( boucle == 1)
    {
    printf("%s@sam:~ %s> ", nom, (getcwd(cwd, sizeof(cwd))));
    fgets(saisie,MAX_INPUT_SZ,stdin);
    printf("\n");
    char **argv = split_input(saisie);

    if(argv == NULL)
    {
    fprintf(stderr, "Cannot split command line, not enough memory\n");
    continue;
    }

    free(backup[u]);
    backup[u] = strdup(argv[0]); // <-- passing argv[0], not argv
    // but perhaps what you really want
    // is strdup(saisie)
    u = (u + 1) % MAXCMD;

    b = switchcmd(argv,backup,b,u);
    start(argv,b);
    b = 0; //débloquage fonction start
    free_argv(argv);
    }

你也在做

backup[u] = strdup(cmd);

但问题是 cmdchar 的数组指针,strdup期待一个 const char* ,您传递的类型错误。应该是strdup(cmd[0])或者 strdup(saisie)如果你想存储整个命令。

关于c - 我自己的 C Shell 的历史问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49712756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com