Sparsh_Mishra
Sparsh_Mishra

Reputation: 61

Can we add more options in getopt?

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;
}   

Upvotes: 1

Views: 80

Answers (1)

chqrlie
chqrlie

Reputation: 144695

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;
}   

Upvotes: 1

Related Questions