/* argv.c - collect argv array from command line * 2009.09.24 Neal Nelson * * I can't think how to get around the extra copy and not waste space. * Goes through the for loop one too many times. This version seems not * better than the first version. */ #include #include #define MAXLINE 80 #define MAXWORDS 3 char *getArg(char *buf, char *word); void *malloc(); /* should probably use calloc in general */ main() { char buf[MAXLINE]; /* fgets reads only MAXLINE-1 and adds zero */ char word[MAXLINE+1]; /* add one for zero at end of line */ char *argv[MAXWORDS+1]; /* make room for zero at end of argv array */ char *p; int i,argc; /* Display argv for command lines until EOF (^d) at begin of line */ while (fgets(buf, MAXLINE, stdin) != NULL) { /* fill up argv */ p = buf; for (argc = 0; (p = getArg(p,word)) != NULL && argc < MAXWORDS; argc++) { printf(" >%s\n", word); argv[argc] = (char *)malloc(strlen(word) + 1); strcpy(argv[argc],word); /* an extra copy operation */ } argv[argc] = (char *)0; /* Put NULL pointer to char at end of argv array */ /* now print out argv */ printf("The words in argv (max %d) ...\n",MAXWORDS); for (i = 0; i < argc; i++) { printf("%s\n",argv[i]); } } } /* Copy next word after bufptr to word array (allocated by caller). * Return new bufptr or NULL if no word found */ char* getArg(char *bufptr, char *word) { char *p; int i; for (p = bufptr; isspace(*p); p++); /* skip leading spaces */ for (i = 0; !isspace(*p) && *p != '\0'; ) /* get next word */ { word[i++] = *p++; } word[i] = '\0'; return ( (i == 0) ? NULL : p ); /* if (i == 0) return NULL; else return p; */ }