I limited this code for now just to do some basic calculation like addition and subtraction so as to get an idea of how getopt
works.
What I am trying to achieve is : ./a.out -a 20 20 -s 40 40
[result = 40
and 0
]
I'm new to C, so kindly let me know the mistakes in my code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main(int argc, char *argv[]) {
FILE *file1 = fopen("Results.txt", "a");
char ch;
int res;
while ((ch = getopt(argc, argv, "a:s:")) != EOF)
switch (ch) {
case 'a':
res = add(atoi(optarg), atoi(argv[3]));
fprintf(file1, "%i\n", res);
break;
case 's':
res = subtract(atoi(optarg), atoi(argv[3]));
printf("%i \n", res);
fprintf(file1, "%i\n", res);
break;
default:
fprintf(stderr, "No such option");
return 1;
}
argc -= optind;
argv += optind;
printf("Opind = %i, argc = %i, argv = %i \n", optind, argc, argv);
fprintf(file1, "\nWritten to file\n");
fclose(file1);
return 0;
}
There are multiple problems in your code:
you should define ch
as int
to accommodate for the possible return values of getopt
. getopt
returns an int
that is either a matching option character or the value -1
if no more options are present in the argv
array. The char
type is unsigned by default on some platforms (and it is a sensible choice to make it so), hence on these platforms ch != EOF
will be always true.
the return value of getopt
when there are no more options is -1
, not EOF
which is very commonly defined as -1
but only specified as being negative.
You do not check if fopen()
succeeded, producing undefined behavior if the file cannot be created or open for writing in append mode.
you do not check if there are enough arguments for the -a
and -s
options.
the second argument to add
and subtract
is always argv[3]
. It should be the next argument in the argv
array, argv[optind]
, and you should skip it after use.
argv
canot be passed to printf
for the %i
conversion specifier. It is unclear what you intend to do by that.
Here is a modified version:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main(int argc, char *argv[]) {
FILE *file1 = fopen("Results.txt", "a");
int ch, res;
if (file1 == NULL) {
fprintf(stderr, "cannot open Results.txt for appending: %s\n",
strerror(errno));
return 1;
}
while ((ch = getopt(argc, argv, "a:s:")) != -1) {
switch (ch) {
case 'a':
if (optind >= argc) {
fprintf(stderr, "not enough arguments\n");
return 1;
}
res = add(atoi(optarg), atoi(argv[optind]));
optind++;
//printf("%i\n", res);
fprintf(file1, "%i\n", res);
break;
case 's':
if (optind >= argc) {
fprintf(stderr, "not enough arguments\n");
return 1;
}
res = subtract(atoi(optarg), atoi(argv[optind]));
optind++;
//printf("%i\n", res);
fprintf(file1, "%i\n", res);
break;
default:
fprintf(stderr, "No such option");
return 1;
}
}
argc -= optind;
argv += optind;
printf("Opind = %i, argc = %i\n", optind, argc);
fprintf(file1, "\nWritten to file\n");
fclose(file1);
return 0;
}