C 指针数组未按预期打印,它用最后一个输入替换所有内容

标签 c arrays string pointers

我已经努力解决这个问题两天了,但似乎没有任何效果! 我正在用 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;
}

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

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

1.测试2

2.测试2

有什么意见可以解决这个问题吗? (我使用TCC编译)

最佳答案

修改这部分

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++;
    }

编辑的 strdup() 在 Windows 上不起作用,因为它是 POSIX 特定的。

what happens in your case

char给定命令[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]---------|  

关于C 指针数组未按预期打印,它用最后一个输入替换所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19569334/

相关文章:

从文本中删除标点符号(符号 & 除外)

java - 在字符串数组中加载 .text 文件

c - 不使用字符串的可变长度算术计算器?

c - 需要解释此代码

javascript - JavaScript中的数组遍历填充两个 map

java - Int 数组填充最后一个 int

Java正则表达式与两个条件混淆

c - 为什么“while(!feof(file))”总是错误的?

c - 结构填充和包装

php - 如何使用 php 按数字顺序对这个数组进行排序