2016-10-03 6 views
0

#をコメント文字として認識するシェルをcで記述しようとしています。たとえば、 "ls#This is a comment"というコマンドを入力すると、プログラムは#の後の文字を認識してはなりません。ここでコメントを認識するcでシェルを作成する

は、私が現在持っているコードは次のとおりです。

/* See Chapter 5 of Advanced UNIX Programming: http://www.basepath.com/aup/ 
* for further related examples of systems programming. (That home page 
* has pointers to download this chapter free. 
* 
* Copyright (c) Gene Cooperman, 2006; May be freely copied as long as this 
* copyright notice remains. There is no warranty. 
*/ 

/* To know which "includes" to ask for, do 'man' on each system call used. 
* For example, "man fork" (or "man 2 fork" or man -s 2 fork") requires: 
* <sys/types.h> and <unistd.h> 
*/ 
#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <string.h> 

#define MAXLINE 200 /* This is how we declare constants in C */ 
#define MAXARGS 20 

/* In C, "static" means not visible outside of file. This is different 
* from the usage of "static" in Java. 
* Note that end_ptr is an output parameter. 
*/ 
static char * getword(char * begin, char **end_ptr) { 
    char * end = begin; 

    while (*begin == ' ') 
     begin++; /* Get rid of leading spaces. */ 
    end = begin; 
    while (*end != '\0' && *end != '\n' && *end != ' ') 
     end++; /* Keep going. */ 
    if (end == begin) 
     return NULL; /* if no more words, return NULL */ 
    *end = '\0'; /* else put string terminator at end of this word. */ 
    *end_ptr = end; 
    if (begin[0] == '$') { /* if this is a variable to be expanded */ 
     begin = getenv(begin+1); /* begin+1, to skip past '$' */ 
    if (begin == NULL) { 
     perror("getenv"); 
     begin = "UNDEFINED"; 
     } 
    } 
    return begin; /* This word is now a null-terminated string. return it. */ 
} 

/* In C, "int" is used instead of "bool", and "0" means false, any 
* non-zero number (traditionally "1") means true. 
*/ 
/* argc is _count_ of args (*argcp == argc); argv is array of arg _values_*/ 
static void getargs(char cmd[], int *argcp, char *argv[]) 
{ 
    char *cmdp = cmd; 
    char *end; 
    int i = 0; 

    /* fgets creates null-terminated string. stdin is pre-defined C constant 
    * for standard intput. feof(stdin) tests for file:end-of-file. 
    */ 
    if (fgets(cmd, MAXLINE, stdin) == NULL && feof(stdin)) { 
     printf("Couldn't read from standard input. End of file? Exiting ...\n"); 
     exit(1); /* any non-zero value for exit means failure. */ 
    } 
    while ((cmdp = getword(cmdp, &end)) != NULL) { /* end is output param */ 
     /* getword converts word into null-terminated string */ 

     if (strchr(cmdp, '#') != NULL) { 

     } 

     argv[i++] = cmdp; 
     /* "end" brings us only to the '\0' at end of string */ 
    cmdp = end + 1; 
    } 
    argv[i] = NULL; /* Create additional null word at end for safety. */ 
    *argcp = i; 
} 

static void execute(int argc, char *argv[]) 
{ 
    pid_t childpid; /* child process ID */ 

    childpid = fork(); 
    if (childpid == -1) { /* in parent (returned error) */ 
     perror("fork"); /* perror => print error string of last system call */ 
     printf(" (failed to execute command)\n"); 
    } 
    if (childpid == 0) { /* child: in child, childpid was set to 0 */ 
     /* Executes command in argv[0]; It searches for that file in 
    * the directories specified by the environment variable PATH. 
     */ 
     if (-1 == execvp(argv[0], argv)) { 
      perror("execvp"); 
      printf(" (couldn't find command)\n"); 
     } 
    /* NOT REACHED unless error occurred */ 
     exit(1); 
    } else /* parent: in parent, childpid was set to pid of child process */ 
     waitpid(childpid, NULL, 0); /* wait until child process finishes */ 
    return; 
} 

int main(int argc, char *argv[]) 
{ 
    char cmd[MAXLINE]; 
    char *childargv[MAXARGS]; 
    int childargc; 

    while (1) { 
     printf("%% "); /* printf uses %d, %s, %x, etc. See 'man 3 printf' */ 
     fflush(stdout); /* flush from output buffer to terminal itself */ 
    getargs(cmd, &childargc, childargv); /* childargc and childargv are 
      output args; on input they have garbage, but getargs sets them. */ 
     /* Check first for built-in commands. */ 
    if (childargc > 0 && strcmp(childargv[0], "exit") == 0) 
      exit(0); 
    else if (childargc > 0 && strcmp(childargv[0], "logout") == 0) 
      exit(0); 
     else 
     execute(childargc, childargv); 
    } 
    /* NOT REACHED */ 
} 
+0

私は – buhtz

+0

を提供[MCVE]です。問題を示すためにコードサンプルを減らそうとしてください。プログラム全体は必要ありません。 – mloomis

+0

__minimal__がを暗示何buhtzキーワード – buhtz

答えて

0

あなたはwhileループの外にテストを配置する必要があります。

static void getargs(char cmd[], int *argcp, char *argv[]) 
{ 
    char *cmdp = cmd; 
    char *end, *hash; 
    int i = 0; 

    /* fgets creates null-terminated string. stdin is pre-defined C constant 
    * for standard intput. feof(stdin) tests for file:end-of-file. 
    */ 
    if (fgets(cmd, MAXLINE, stdin) == NULL && feof(stdin)) { 
     printf("Couldn't read from standard input. End of file? Exiting ...\n"); 
     exit(1); /* any non-zero value for exit means failure. */ 
    } 
    // check if we have a comment 
    hash = strchr(cmd,'#'); 
    if(hash != NULL){ 
     // just overwrite it with NULs 
     while(*hash != '\0'){ 
      *hash = '\0'; 
      hash++; 
     } 
    } 
    while ((cmdp = getword(cmdp, &end)) != NULL ) { /* end is output param */ 
     /* getword converts word into null-terminated string */ 
     argv[i++] = cmdp; 
     /* "end" brings us only to the '\0' at end of string */ 
    cmdp = end + 1; 
    } 
    argv[i] = NULL; /* Create additional null word at end for safety. */ 
    *argcp = i; 
} 
関連する問題