我们可以在getopt中添加更多选项吗?

时间:2018-10-08 06:07:08

标签: c unix posix getopt

我现在仅将此代码限制为进行一些基本计算(例如加法和减法),以便了解getopt的工作原理。

我要实现的目标是:./a.out -a 20 20 -s 40 40 [结果= 400]

我是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 :(得分:1)

您的代码中存在多个问题:

  • 您应将ch定义为int,以适应getopt的可能返回值。如果getopt数组中没有更多选项,则int返回一个-1,它可以是匹配的选项字符或值argv。在某些平台上,char类型默认是无符号的(这样做是明智的选择),因此在这些平台上ch != EOF始终为真。

  • 在没有更多选项的情况下,getopt的返回值为-1,而不是EOF,通常将其定义为-1,而仅将其指定为否定的。

  • 您不会检查fopen()是否成功,如果无法创建文件或无法以追加模式打开该文件以进行写入,则会产生不确定的行为。

  • 您不会检查-a-s选项是否有足够的参数。

  • addsubtract的第二个参数始终为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;
}