purpleHaz3003 2023-03-17 21:12 采纳率: 100%
浏览 73
已结题

c语言使用linux shell的vim编程,在使用指针的时候,值莫名其妙消失了。

图一结果展示

img

图二问题部分代码

img

经过测试 在这个//fill the command structrue部分之后,这里的token[2]就消失了,我测试的用例是“abc;”, 测试结果为图1

command.c

#include <string.h>
#include "command.h"
#include <stdio.h>
#include <stdlib.h>

// whether is separator
int separator(char *token)
{
        int i = 0;
        char *commandSeparators[] = {pipeSep, conSep, seqSep, NULL};

        while(commandSeparators[i] != NULL) {
            if(strcmp(token, commandSeparators[i]) == 0)
            {
                return 1;
            }
            ++i;
        }

    printf("\nin separator\ntoken: %s\n", token);

        return 0;
}

// fill one command structure with details
void fillCommandStructure(Command *cp, int first, int last, char *sep)
{
    cp->first = first;
        cp->last = last - 1;
    cp->sep = sep;
}

// process standard in/out redirections in a command
void searchRedirection(int tknum, char (*token)[MAX_NUM_COMMANDS], Command *cp)
{
    int i;
    for( i = cp->first; i <= cp->last; ++i)
    {
        if(strcmp(token[i], "<") == 0)
        {
            // convert from char array to char
            int k = 0;
            char t[cp->last-i];
            for(int j = i + 1; j <= cp->last; j++)
            {
                t[k] = token[j][0];
                ++k;
            }

            // dynamic allocate memory
            cp->stdin_file = (char*)malloc(cp->last-i);

            for(int l = 0; l < cp->last -i; l++)
            {
                cp->stdin_file[l] = t[l];
            }

            cp->stdin_file[cp->last-i] = '\0';

            ++i;

        } else if (strcmp(token[i], ">") == 0)
        {
            int k = 0;
                        char t[cp->last-i];
                        for(int j = i + 1; j <= cp->last; j++)
                        {
                                t[k] = token[j][0];
                            ++k;
            }

            cp->stdout_file = (char*)malloc(cp->last-i);

                        for(int l = 0; l < cp->last - i; l++)
            {
                cp->stdout_file[l] = t[l];
            }

            cp->stdout_file[cp->last-i] = '\0';

            ++i;
        }
    }
}

// build command line argument vector for execvp function
void buildCommandArgumentArray(char (*token)[MAX_NUM_COMMANDS], Command *cp)
{
    int n = cp->last - cp->first + 1;

    printf("n: %d\n", n);

    // re-allocate memoery for argument vector
    cp->argv = (char**) realloc(cp->argv, sizeof(char*)*n );
    
    if(cp->argv == NULL)
    {
        perror("realloc");
        exit(1);
    }

    // build the argument vector
    int i;

    int k = 0;



    printf("first: %d\n last: %d\n", cp->first, cp->last);

    for(i = cp->first; i <= cp->last; ++i)
    {
        if(strcmp(token[i], ">") == 0 || strcmp(token[i], "<") == 0)
            ++i;
        else
        {
            cp->argv[k] = token[i];
            printf("k %d\nargvk %s\ntoken %s\n", k, cp->argv[k], token[i]);
            ++k;
        }
    }

    cp->argv[k] == NULL;
}

int separateCommands(char (*token)[MAX_NUM_COMMANDS], Command command[], int nTokens)
{
    for(int i = 0; i < nTokens;++i)
        {
                printf("token: %s\n", token[i]);
        }

        // if line is empty
    
    if (nTokens == 0)
        return 0;    
    
    // check the first token
    
    if (separator(token[0]))
        return -3;

    // check the last token, add ";" if necessary
    
    if (!separator(token[nTokens-1]))
    {
        strcpy(token[nTokens], seqSep);
        ++nTokens;
    }

    //fill the command structure

    int first = 0;
    int last = 0;
    char *sep;
    int c = 0;

    for(int i = 0; i < nTokens; ++i)
    {
        last = i;
        if (separator(token[i]))
        {
            sep = token[i];
            
            if(first == last)
                return -2;

            fillCommandStructure(&(command[c]), first, last, sep);
            ++c;

            first = i + 1;
        }
    }

    printf("\nafter fill\n");

    for(int i = 0; i < nTokens;++i)
        {
                printf("token: %s\n", token[i]);
        }


    // check the last token of the last command
    if (strcmp(token[last], pipeSep) == 0)
        return -4;

    int nCommands = c;

    // handle standard in/out redirection and build command line argument vector
    
    for (int i=0; i < nCommands; ++i)
    {
        searchRedirection(nTokens, token, &(command[i]));
        buildCommandArgumentArray(token, &(command[i]));
    }

    return nCommands;

command.h

#define MAX_NUM_COMMANDS 1000

#define pipeSep "|"
#define conSep "&"
#define seqSep ";"

struct CommandStruct {
        int first;
        int last;
        char *sep;

    // new fields
    
    char ** argv;
    char *stdin_file;
    char *stdout_file;
};

typedef struct CommandStruct Command;

int separateCommands(char (*token)[MAX_NUM_COMMANDS], Command command[], int cmd_num);


main.c

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

#include "command.h"

char* s_gets(char* st, int n)
{
        char* ret_val;
        int i = 0;

        ret_val = fgets(st, n, stdin);

        if(ret_val)
        {
                while (st[i] != '\n' && st[i] != '\0')
                        i++;
                if (st[i] == '\n')
                {
                        st[i] = '\0';
                }
                else
                {
                        while (getchar() != '\n')
                        {
                                continue;
                        }
                }
        }

        return ret_val;
}

char* tostring(char des[], char src)
{
    des[0] = src;

    des[1] = '\0';

    return des;
}

int main()
{
    while(1)
    {
        char str[MAX_NUM_COMMANDS];

    char tokens[2][MAX_NUM_COMMANDS];

        int cmd_num = 0;

        printf("$\n");

        s_gets(str, MAX_NUM_COMMANDS);

    cmd_num = strlen(str);

    for(int i = 0; i < cmd_num; ++i)
    {
        tostring(tokens[i], str[i]);    
    }

        Command cmdlst[MAX_NUM_COMMANDS];

        cmd_num = separateCommands(tokens, cmdlst, cmd_num);

    puts("");

    printf("return value is: %d\n",cmd_num);

    puts("");

    for(int i = 0; i < cmd_num; ++i)
        {
            printf("fst %d\n", cmdlst[i].first);
            printf("lst %d\n", cmdlst[i].last);
          printf("sep %s\n", cmdlst[i].sep);
        if(cmdlst[i].stdin_file != NULL)
            printf("stdin file: %s\n", cmdlst[i].stdin_file);
        if(cmdlst[i].stdout_file != NULL)
            printf("stdout file: %s\n", cmdlst[i].stdout_file);
        
        puts("");    
    }

    // clean pointer
    for(int i = 0; i < cmd_num; ++i)
    {
        if(cmdlst[i].stdin_file != NULL)
            free(cmdlst[i].stdin_file);
        if(cmdlst[i].stdout_file != NULL)
            free(cmdlst[i].stdout_file);
    }

    puts("");
    }

    return 0;
}

  • 写回答

4条回答 默认 最新

  • MarkHan_ 2023-03-17 22:30
    关注

    该回答引用GPTᴼᴾᴱᴺᴬᴵ
    根据提供的代码和信息,出现问题的地方可能是在fillCommandStructure函数中:

    void fillCommandStructure(Command *cp, int first, int last, char *sep)
    {
        cp->first = first;
        cp->last = last - 1;
        cp->sep = sep;
    }
    
    
    

    其中,cp->last 的值是 last - 1。由于 last 的值是从 0 开始计数的索引,因此在使用此索引访问数组时,数组中的最后一个元素将被忽略。这可能是导致出现问题的原因。
    ·
    为了解决这个问题,你可以尝试将 fillCommandStructure 函数中的 cp->last = last - 1 修改为 cp->last = last,或者在调用 fillCommandStructure 函数时将 last 参数传递为实际上应该是最后一个元素的索引值加 1,例如 last + 1。
    ·
    另外,fillCommandStructure 函数的调用在 separator 函数中进行。因此,还应该确保 fillCommandStructure 函数的调用不会在数组的最后一个元素上执行。你可以通过在 for 循环中将 i < nTokens - 1 作为条件来实现这一点,以避免在数组的最后一个元素上调用该函数。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 3月25日
  • 已采纳回答 3月17日
  • 赞助了问题酬金20元 3月17日
  • 赞助了问题酬金20元 3月17日
  • 展开全部

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分