Можем ли мы добавить больше опций в getopt? - PullRequest
0 голосов
/ 08 октября 2018

Я ограничил этот код сейчас только для того, чтобы выполнить некоторые базовые вычисления, такие как сложение и вычитание, чтобы получить представление о том, как работает getopt.

Я пытаюсь достичь: ./a.out -a 20 20 -s 40 40 [результат = 40 и 0]

Я новичок в C, поэтому, пожалуйста, дайте мне знать об ошибках в моем коде.

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

1 Ответ

0 голосов
/ 08 октября 2018

В вашем коде есть несколько проблем:

  • вы должны определить ch как int, чтобы учесть возможные возвращаемые значения getopt.getopt возвращает int, который является либо совпадающим символом опции, либо значением -1, если в массиве argv больше нет опций.Тип char по умолчанию не подписан на некоторых платформах (и это разумный выбор), поэтому на этих платформах ch != EOF всегда будет истинным.

  • Возвращаемое значение getopt, когда больше нет опций, равно -1, а не EOF, которое обычно определяется как -1, но указывается только как отрицательное.

  • Youне проверяйте, успешно ли fopen(), что приводит к неопределенному поведению, если файл не может быть создан или открыт для записи в режиме добавления.

  • вы не проверяете, достаточно ли аргументов для *Опции 1031 * и -s.

  • второй аргумент для add и subtract всегда argv[3].Это должен быть следующий аргумент в массиве argv, argv[optind], и вы должны пропустить его после использования.

  • argv не может быть передано printf для %i спецификатор преобразования.Непонятно, что вы собираетесь этим делать.

Вот модифицированная версия:

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