我的CD和历史记录结果:

sgraham @ myshell:/ home / class / sgraham / proj1> cd ..(工作正常)

sgraham @ myshell:/ home / class / sgraham> cd ..(不起作用)

sgraham @ myshell:/ home / class / sgraham> cd ..(不起作用)
cd:参数过多

sgraham @ myshell:/ home / class / sgraham>历史

sgraham @ myshell:/ home / class / sgraham>(不打印历史记录)



#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>


#define MAX_COMMAND_SIZE 80
#define MAX_ARGS 9
#define HIS_SIZE 100


typedef struct
{
  int argument;                             // userCom arguments
  char *arg[MAX_ARGS + 1];                  // userCom arguments array
  char *history[HIS_SIZE];                  //history array
  char *input;                          // hold input file
  char *output;                        // hold output file
} Command;


int main()
{
    Command userCom = {0};                       //holds userCom struct
    const char *whitespace = " \n\r\t\v\f";      // userCom delimiting chars
    char* username = getenv("USER");             //Get user name
    char* curDirect = getenv("HOME");            //get cwd
    char* token[MAX_ARGS];
    char* cwd;
    char* buf;
    char* cmd;
    char buffer[MAX_COMMAND_SIZE + 1];       //hold userCom line
    //char history[HIS_SIZE][MAX_ARGS +1];  //2D array for history
    int tok = 0;
    int new;
    int i;
    int limit;
    int last = 0;
    int hist = 0;                           //initialize history size to 0
    long size;
    struct stat buff;                       //holds file information


    //gets current working directory and also changes buffer if necessary
    size = pathconf(".", _PC_PATH_MAX);
    if ((buf = (char *)malloc((size_t)size)) != NULL)
    cwd = getcwd(buf, (size_t)size);

    while(1){

    //prints users prompt
    printf("\n%s@myshell:%s>", username,cwd);

    //gets string from userCom line
    fgets(buffer, MAX_COMMAND_SIZE + 1, stdin);

    buffer[strlen(buffer)-1] = 0 ;//set null

    //set-up history function
     userCom.history[last% HIS_SIZE] = cmd;
     last++;

    //parses tokens and looks for delimiters
    token[tok] = strtok(buffer,whitespace);
    while(token[tok])
    {
        ++tok;
        if(tok == MAX_ARGS)
        printf("Reached MAX userCom arguments");
        break;

        token[tok] = strtok(NULL, whitespace);
    }

    i =0;
    //sort tokens based on special characters
    for (;i<tok;++i)

    {
        if(!strcmp(token[i], "<"))
            {
             userCom.output = token[++i];
            }
        else if(!strcmp(token[i], ">"))
        {
            userCom.input = token[++i];
        }
        else if (token[i][0] == '$')
        {
          char* toktok = getenv((const char*)&token[i][1]);

          if (!toktok)
            {
              printf("%s: ERROR: variable.\n", token[i]);
              return 0;
            }
          else
            {
              userCom.arg[userCom.argument] = toktok;
              ++(userCom.argument);
            }
        }

      else
        {
          userCom.arg[userCom.argument] = token[i];
          ++(userCom.argument);

        }
    }
        tok = 0;
        userCom.arg[userCom.argument] = 0;


    //handles the "cd" command
        if((strcmp(userCom.arg[0],"cd") == 0))
        {
            if (userCom.argument > 2)
          printf("cd: Too many arguments\n");

          // change directories if valid target and update cwd

          else if (userCom.argument == 1)
        {
          new = chdir(cwd);
          if (new != 0)
              printf("%s: No such file or directory\n");

          // if no argument is given, new directory should be $HOME

              else
            {
              new = chdir(curDirect);

              // get the new current working directory

              size = pathconf(".", _PC_PATH_MAX);
              if ((buf = (char *)malloc((size_t)size)) != NULL)
                cwd = getcwd(buf, (size_t)size);
            }
        }
      }//end "cd" function

      //handles the echo command
      else if(strcmp(userCom.arg[0], "echo") == 0)
      {
        int p;
        for(p=1;p < userCom.argument; ++p)
        printf("%s ", userCom.arg[p]);

      }//ends echo function

      //handles exit
      else if(strcmp(userCom.arg[0], "exit") == 0)
      {
        exit(0);
      }
      //handles history functions
      else if(strcmp(userCom.arg[0], "history") == 0)
      {
        int j;
        for(j = last,  limit = 0; userCom.history[j] != NULL && limit != HIS_SIZE ; j = (j -1)% HIS_SIZE, limit++)
        printf(" %s ",userCom.history[j]);
      }
      else {
      break;
      }

      }//end while 1 loop

    return 0;
}//End int main

最佳答案

while(token[tok])
{
    ++tok;
    if(tok == MAX_ARGS)
    printf("Reached MAX userCom arguments");
    break;

    token[tok] = strtok(NULL, whitespace);
}


此循环在第一次中断。 if应该像

if(tok == MAX_ARGS) {
    printf("Reached MAX userCom arguments");
    break;
}


同样,userCom.argument永远不会设置回zero,这会导致cd ..首次工作。

关于c - 我的CD和历史记录功能遇到问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22301356/

10-11 16:38