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

标签 c unix posix getopt

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

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

最佳答案

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

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

  • 当没有更多选项时,getopt 的返回值是-1,而不是EOF,后者通常被定义为-1 但仅指定为负数。

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

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

  • addsubtract 的第二个参数总是 argv[3]。它应该是 argv 数组中的下一个参数,argv[optind],您应该在使用后跳过它。

  • 对于 %i 转换说明符,
  • argv 不能传递给 printf。目前尚不清楚您打算这样做。

修改后的版本:

#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 中添加更多选项吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52696278/

相关文章:

c - 如何判断一个socket被另一个线程shutdown()?

c - ftruncate() 的参数是什么?

C11 附件 K : "objects that overlap"

linux - 用 n 步旋转文本文件中的行

c - Unix: "ls -l"在哪里获取设备大小字段中的逗号分隔值?

检查页面是否被锁定?

c - 为什么在进程退出时数据没有被刷新到文件?

C - 基于变量的 For 循环没有迭代正确的次数

linux - linux/unix系统中管道符/管道符(竖线字符 "|")的可执行文件是什么

c - 使用 gcc 线程的 POSIX 程序问题