自己做的命令行分析函数包,利用链表把输入命令行中的参数全部分离,并可以转换成二维字符串指针,内附调试源代码(也可以作为实例看待,源代码中附了详细的注释,希望大家有用),对了发现问题请急时对我指正,谢谢啦。
老规矩,把代码贴一遍吧。。呵呵 /* cmd.h */ #ifndef __CMD_H #define __CMD_H#include "cmd.cpp"
/* Create an argument structure and return with its pointer */ extern struct cmdlst *create_argument(char *);
/* Add an argument to a linked list */ extern void add_argument(struct cmdlst *);
/* Free a linked list, recycle the resource */ extern void free_cmdlinkedlst(void);
/* Split the key word and arguments from a line of command, and gather them together into a linked list. */ extern void extract_cmd(char *);
/* Display key word and arguments in the linked list. (DEBUG ONLY) */ extern void debug_display_cmd(void);
/* Get the count of arguments that in the linked list. */ extern int argcount(void);
/* Convert the linked list into a double-pointer */ extern char **convert(int *argcount);
/* Free a two dimension character pointer */ extern void free_two_dimension_pointer(char **,int);
#endif /* cmd.cpp */ #define SPACE 32 #define MAX_ARGUMENT_LEN 80
/* Programmer nickname: Yuki or Greentea Modify history: 2005-06-23 21:23 (Created & Tested); 2005-07-14 14:16 (Add function "create_argument()" & fix some bugs) QQ: 87264356 */
struct cmdlst { char argument[MAX_ARGUMENT_LEN]; struct cmdlst *next; };
struct cmdlst *cmdhead; struct cmdlst *cmdcurpos;
struct cmdlst *create_argument(char *argument) { struct cmdlst *p; p=(struct cmdlst *)malloc(sizeof(struct cmdlst)); if(!p) { printf("Cannot allocate memory for structure!\n"); exit(1); } strcpy(p->argument,argument); p->next=NULL; return p; }
void add_argument(struct cmdlst *arg) { if(!cmdhead) { /* If the list head points to NULL, add the first item to it. */ cmdhead=(struct cmdlst *)malloc(sizeof(struct cmdlst)); if(!cmdhead) { printf("Cannot allocate memory for structure!\n"); exit(1); } cmdhead=arg; cmdhead->next=NULL; cmdcurpos=cmdhead; } else { /* Add an item to the tail of the linked list. */ cmdcurpos->next=arg; cmdcurpos=arg; cmdcurpos->next=NULL; } }
void free_cmdlinkedlst(void) { struct cmdlst *p=cmdhead,*bakup; /* Address p of "struct cmdlst" is just used for passing. */ while(p) { bakup=p->next; free(p); p=bakup; } cmdcurpos=NULL; cmdhead=NULL; }
void extract_cmd(char *command) { char *temp,*baktemp,*i,*argbegin; struct cmdlst *p; if(command&&strlen(command)>0) { /* If the linked list has already some data in, empty it! */ if(cmdhead) free_cmdlinkedlst(); /* Get rid of the spaces ahead of the command! */ while(*command==(char)(SPACE)) command++; while(*command) { argbegin=command; /* Get the length of an argument and its tail position */ for(i=command;*i;i++) if(*i==(char)(SPACE)||!*i) break; /* Allocate memory for the argument according to its length. */ temp=(char*)malloc((i-command+2)*sizeof(char)); /* Just bakup the first address of the new allocated string pointer. */ baktemp=temp; if(!temp) { printf("Cannot allocate memory for string!\n"); exit(1); } /* Copy the argument to the new allocated string pointer. */ for(;argbegin<i;argbegin++) *temp++=*argbegin; /* End of the string, Don't forget it! */ *temp='\0'; /* Create a new structure */ p=create_argument(baktemp); /* Add the structure to the linked list */ add_argument(p); /* Free the variable temp */ free(baktemp); /* Adjust the position of pointer "command" so as to decrease the times of loop. */ if(!*i||!*(i+1)) break; else { for(;*i;i++) if(*i!=(char)(SPACE)) break; command=i; } } } }
void debug_display_cmd(void) { /* Display arguments in the linked list one by one. */ /* JUST FOR DEBUGING */ struct cmdlst *p=cmdhead; if(p) { while(p) { printf("%s\n",p->argument); p=p->next; } } }
int argcount(void) { /* Get the item count in the linked list */ int count=0; struct cmdlst *p=cmdhead; if(p) { while(p) { count++; p=p->next; } } return count; }
char **convert(int *argc) { int i; /* Get the count of arguments */ int count=argcount(); /* define a double-pointer */ char **arglst=NULL; struct cmdlst *p=cmdhead; if(count>0) { /* Allocate the number of pointers */ arglst=(char **)malloc(count*sizeof(char *)); if(!arglst) { printf("Cannot allocate memory for string pointer array!\n"); exit(1); } for(i=0;i<count;i++) { /* Dynamic allocate the length of each pointer that points to the string. */ arglst[i]=(char*)malloc((strlen(p->argument)+1)*sizeof(char)); if(!arglst[i]) { printf("Cannot allocate memory for string!\n"); exit(1); } strcpy(arglst[i],p->argument); p=p->next; } *argc=count; } return arglst; }
void free_two_dimension_pointer(char **s,int count) { /* Free a two dimension character pointer */ int i; if(s) { for(i=0;i<count;i++) free(s[i]); free(s); } } /* debug_cmd.cpp */ #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h>
#include "cmd.h"
int main() { char command[80]={0}; char **arglst=NULL; int count,i; do { free_two_dimension_pointer(arglst,count); printf("cmd> "); gets(command); extract_cmd(command); arglst=convert(&count); printf("ech \n"); for(i=0;i<count;i++) printf("%s\n",arglst[i]); }while(strcmp(arglst[0],"exit")); getch(); free_cmdlinkedlst(); free_two_dimension_pointer(arglst,count); return 0; }