2

我现在正在努力解决这个问题 2 天,但似乎没有任何效果!我正在用 C 语言制作一个 shell,我正在尝试实现历史命令(它将保留用户给出的所有命令的历史记录)。这是我的代码的简化版本(删除了不必要的代码和函数)。

#include <stdio.h>
#include <string.h>

int main()
{
int doLoop = 1;
int i=0;
int c=0;
char givenCommand[100];
char *history[20];
char *newlinePos; /* pointer to the '\n' character in the input C string */

/* Print the header */
printf("Operating Systems Shell (Fall 2013)\n");
printf("Iacovos Hadjicosti\n");
printf("\n");

while(doLoop==1) /* Check if it should do the loop again */
{
    printf("CSC327>"); /* Print a new prompt line */
    fgets(givenCommand, sizeof(givenCommand), stdin); /* get input */

    newlinePos = strchr(givenCommand,'\n'); /* point newlinePos to the '\n' character */
    if(newlinePos!=NULL)
    {
        *newlinePos = '\0'; /* replace it with the null character */
    }

    if(strcmp(givenCommand,"exit")==0)
    {
        doLoop = 0; /* Do not do the loop again */
    }
    else if(strcmp(givenCommand,"history")==0)
    {

        for(i=0; i<c; i++)
        {
            printf("%d. %s\n", i+1, history[i]);
        }
    }
    else
    {
        if(strcmp(givenCommand,"")!=0) /* if input was not empty.. */
        {
            printf("Command not found!\n"); /* show wrong command message */
        }
    }       

    history[c] = givenCommand;
    c++;
}
return 0;
}

这获取输入,将其放入 givenCommand,检查它是哪个命令,然后将其放入历史数组中。当用户给出“历史”命令时,它应该打印历史数组中的所有命令。相反,它只打印给出的最后一条命令,c 次(c 是给出的命令总数)。

例如,如果用户输入“Test1”,然后第二次输入“Test2”,当他第三次输入“history”时,将输出以下内容:

1.测试2

2.测试2

任何意见如何解决这个问题?(我是用TCC编译的)

4

3 回答 3

2

您需要复制givenCommandhistory,而不是分配其指针:

strcpy(history[c], givenCommand);

为此,您必须进行更改history,以便为命令本身留出空间:

char history[20][100];

作为文体说明:您可以将-body 放在每个命令continue;的末尾,这样您就可以省略该部分。因为您可以使用立即结束循环:ifelse"exit"break;

if(strcmp(givenCommand, "exit") == 0){
    break; /* end the loop now */
}

if(strcmp(givenCommand, "history") == 0){
    /* do history stuff */
    continue; /* go back to the beginning of the loop */
}
于 2013-10-24T14:58:17.457 回答
2

修改这部分

else if(strcmp(givenCommand,"")==0) /* if input was empty.. */
    {
        printf("Command not found!\n"); /* show wrong command message */
    }

else
    {

    history[c]=malloc(strlen(givenCommand)+1); //allocate memory

    //check malloc allocated memory or failed 

    if(history[c]==NULL)  
        {
        printf("malloc function failed \n"); 
        perror("ERROR");
        exit(EXIT_FAILURE);
        // exit(1); //if you don't want to exit then break loop with break;  
        // As alk suggested, The use of EXIT_SUCCESS and EXIT_FAILURE is 
        // slightly more portable (to non-UNIX environments)   
        // than the use of 0 and some nonzero value like  1  or  -1. 
        }  

    strcpy(history[c], givenCommand); // if you can able to use Unix platform you can also use this instead of allocating memory copyinghistory[c] =strdup( givenCommand );
    c++;
    }

Editedstrdup()不适用于 Windows,因为它是 POSIX 特定的。

你的情况会发生什么

char givenCommand[100];是静态声明地址是一样的。

when you enter "test1"  

                    getcommandname starting address
                    test1
                    ^
                    | 
history[0]----------|


when you enter "test2"                          
                    getcommandname starting address
                    test2
                    ^
                    | 
history[0]----------|
history[1]----------| 


When you enter "history"                        
                   getcommandname starting address
                   history
                   ^
                   | 
history[0]---------|
history[1]---------| 
history[2]---------|  
于 2013-10-24T15:15:39.110 回答
0

因为每次输入之后givenCommand指向的内容都在变化,所以需要保存输入的内容,而不是保存输入的指针。所以可能你可以使用strcopy函数来保存输入的字符串

于 2013-10-24T15:29:34.030 回答