c - Parse string into argv/argc -
is there way in c parse piece of text , obtain values argv , argc, if text had been passed application on command line?
this doesn't have work on windows, linux - don't care quoting of arguments.
if glib solution overkill case may consider coding 1 yourself.
then can:
- scan string , count how many arguments there (and argc)
- allocate array of char * (for argv)
- rescan string, assign pointers in allocated array , replace spaces '\0' (if can't modify string containing arguments, should duplicate it).
- don't forget free have allocated!
the diagram below should clarify (hopefully):
aa bbb ccc "dd d" ee <- original string aa0bbb0ccc00dd d00ee0 <- transformed string | | | | | argv[0] __/ / / / / argv[1] ____/ / / / argv[2] _______/ / / argv[3] ___________/ / argv[4] ________________/
a possible api be:
char **parseargs(char *arguments, int *argc); void freeparsedargs(char **argv);
you need additional considerations implement freeparsedargs() safely.
if string long , don't want scan twice may consider alteranatives allocating more elements argv arrays (and reallocating if needed).
edit: proposed solution (desn't handle quoted argument).
#include <stdio.h> static int setargs(char *args, char **argv) { int count = 0; while (isspace(*args)) ++args; while (*args) { if (argv) argv[count] = args; while (*args && !isspace(*args)) ++args; if (argv && *args) *args++ = '\0'; while (isspace(*args)) ++args; count++; } return count; } char **parsedargs(char *args, int *argc) { char **argv = null; int argn = 0; if (args && *args && (args = strdup(args)) && (argn = setargs(args,null)) && (argv = malloc((argn+1) * sizeof(char *)))) { *argv++ = args; argn = setargs(args,argv); } if (args && !argv) free(args); *argc = argn; return argv; } void freeparsedargs(char **argv) { if (argv) { free(argv[-1]); free(argv-1); } } int main(int argc, char *argv[]) { int i; char **av; int ac; char *as = null; if (argc > 1) = argv[1]; av = parsedargs(as,&ac); printf("== %d\n",ac); (i = 0; < ac; i++) printf("[%s]\n",av[i]); freeparsedargs(av); exit(0); }
Comments
Post a Comment