【问题标题】:Can we add more options in getopt?我们可以在 getopt 中添加更多选项吗?
【发布时间】:2018-10-08 06:07:08
【问题描述】:

我暂时限制了这段代码,只是为了做一些基本的计算,比如加法和减法,以便了解getopt 的工作原理。

我想要实现的是:./a.out -a 20 20 -s 40 40 [result = 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;
}   

【问题讨论】:

  • 您可以添加更多选项,但 AFAIK 您不能为一个选项添加更多值。 ./a.out -a 20 -a 20 -s 40 -s 40呢?
  • 虽然不起作用,但它返回了相同的值,有什么建议的增强功能吗?
  • 需要单独处理wach发生,解析后执行操作。对于加/减,最好不要使用 getopt 而是自己解析。
  • 我会在下次使用 getopt 时研究它,我对它很陌生,所以我试图弄清楚它的工作原理。谢谢你的建议:)
  • 您可以使用和递增optind(有关更多详细信息,请参阅@charlie 的答案),但您不应该这样做。这是一种非常罕见的选项用法,会打扰任何用户。长话短说:您在这里使用了错误的工具。

标签: c unix posix getopt


【解决方案1】:

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

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

  • 没有更多选项时getopt的返回值是-1,而不是EOFEOF通常定义为-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;
}   

【讨论】:

  • 这解决了我的问题并帮助我更正确地理解 getopt,请原谅我的错误代码。关于 printf 中的 argv,我实际上想检查值是否增加。
猜你喜欢
  • 1970-01-01
  • 2020-03-23
  • 2013-08-28
  • 1970-01-01
  • 2019-09-25
  • 2018-06-09
  • 2014-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多