I have the following code:
void parse(char *commandLine) {
int rc = 0;
int argc = 0;
char *cmdLine;
char *argv[MAX_ARGS];
filename = NULL;
stdoutFilename = NULL;
stderrFilename = NULL;
cmdLine = strdup(commandLine);
char *param = strtok(cmdLine, " ");
while (param && argc < MAX_ARGS) {
argv[argc++] = param;
param = strtok(NULL, " ");
printf("%s\n", argv[argc-1]);
}
free(cmdLine);
scanOptions(argc, argv);
printf("Filename %s\n", filename);
...
and
void scanOptions(int argc, char *argv[]) {
int c ;
while ((c = getopt (argc, argv, "Df:e:o:")) != -1) {
switch (c) {
case 'D': __debug = 1; break;
case 'f': filename = strdup(optarg); break;
case 'o': stdoutFilename = strdup(optarg); break;
case 'e': stderrFilename = strdup(optarg); break;
default: fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
}
}
}
filename, stdoutFilename
and stderrFilename
are global variables.
If I call the parse method as:
parse("-ftest/testfile.txt") the variable filename is not set and the call to
printf("Filename %s\n", filename); prints "Filename (null)".
What's wrong with that?
There's a few things wrong, that may or may not be the cause of your problem:
Use of freed memory
free(cmdLine);
scanOptions(argc, argv);
You can't free the cmdLine here, since your strtok() calls will assign pointers inside cmdLine to your argv. free() it after scanOptions() , though if you save any optarg pointers directly, they will point into space that you have free()'d - you use strdup() so youre safe in your case.
Resetting getopt()
If you have called getopt previously, you need to reset some of its variables so it can scan again, (see the getopt manpage for an explanation). You need to do:
optind = 0;
Wrong index in argv The first index in argv is by convention the program name, not any program arguments. So make sure your argv[0] isn't any of your arguments. But it needs to be a valid string and not e.g. a NULL pointer.
argv[1] should be the first argument.
Add a sentiel to argv
The traditional argv of main() ends with a NULL pointer, your emulated argv should too. After the while loop, do
argv[argc] = NULL;