简体   繁体   English

多个逗号分隔值的 getopt 错误处理

[英]getopt error handling for multiple comma separated values

how to validate a string variable for multiple combinations of comma separated values received from command line for getopt?如何验证从命令行接收到的逗号分隔值的多个组合的字符串变量用于getopt?

       case 'a' :
                    flaga=1;
                    alg = optarg;
                    printf("you entered option -a \"%s\"\n", optarg);

                    if(strcmp(alg,"lr") == 0 )
                       {
                         ....//valid
                       }
                    else if(strcmp(alg,"lda") == 0 )
                       {
                         ....//valid
                       }
                    else if(strcmp(alg,"knn") == 0 )
                       {
                          ...//valid
                       }
                     """""
                      """"
                    else
                      {
                       printf("wrong value entered for option -a \n");
                       exit();
                       }

option -a can accept these values : "knn","lda","lr","kart","nb","svm" .选项 -a 可以接受这些值: "knn","lda","lr","kart","nb","svm" 。

The above code handles errors perfectly if user passes only single value .如果用户只传递单个值,上面的代码可以完美地处理错误。

But option -a can accept multiple values as comma separated ,但是选项 -a 可以接受多个值以逗号分隔,

                    Eg :   -a knn,lr,lda

User can pass these values in any combination of any values !!用户可以以任何值的任意组合传递这些值!

                    Eg :   -a knn,lr,lda
                    Eg :   -a knn,lda.lr
                    Eg :   -a lda,lr
                    

How to check if user has passed valid values for option -a ?如何检查用户是否为选项 -a 传递了有效值?

The above code i have written is included in switch case and can handle if only single value for option -a is passed .我编写的上述代码包含在 switch case 中,如果仅传递选项 -a 的单个值,则可以处理。

When you allow several options that are separated with a comma, you must split the string at the commas and process every token.当您允许使用逗号分隔的多个选项时,您必须在逗号处拆分字符串并处理每个标记。 One way to split strings is the library funtion strtok from <string.h> .拆分字符串的一种方法是来自<string.h>的库函数strtok Take care to remove whitespace from the tokens when you compare them.比较它们时,请注意从标记中删除空格。

Another question is how you want to represent the result.另一个问题是你想如何表示结果。 One way is to fill an initially zeroes out array of options with ones as appropriate.一种方法是用适当的选项填充最初归零的选项数组。 Another way is to use a bit-combination so that options 0,1 and 3 correspond to 2⁰ + 2¹ + 2³ = 1 + 2 + 8 = 11. That's the method I used below.另一种方法是使用位组合,使选项 0,1 和 3 对应于 2⁰ + 2¹ + 2³ = 1 + 2 + 8 = 11。这就是我在下面使用的方法。

The example program below provides a function multi_opt that parses a list of options that are separated by commas.下面的示例程序提供了一个函数multi_opt ,它解析由逗号分隔的选项列表。 When an unknown option is dound, the program exits immediately.当未知选项被取消时,程序立即退出。 You may opt to return an invalid bit cobination instead and pass the responsibility of error handling to the calling code.您可以选择返回无效的位组合,并将错误处理的责任传递给调用代码。

The function also works when the argument string is empty, in which case no options are set.当参数字符串为空时,该函数也可以工作,在这种情况下没有设置任何选项。 The main function shows how to use that function.. main功能显示如何使用该功能..

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

/*
 *      Return index of str in opt or -1 if it can't be found.
 */
int find_opt(const char *str, const char **opt)
{
    int i;

    for (i = 0; opt[i];i++) {
        if (strcmp(str, opt[i]) == 0) return i;
    }

    return -1;
}

/*
 *      Return a bit combination of the options from opt found in str.
 */
unsigned int multi_opt(const char *str, const char **opt)
{
    unsigned int res = 0u;
    char buf[strlen(str) + 1];
    char *p = buf;

    // copy to modifiable buffer and strip whitespace
    while (*str) {
        if (!isspace((unsigned char) *str)) *p++ = *str;
        str++;
    }

    *p= '\0';

    // split string and process tokens
    p = strtok(buf, ",");
    while (p) {
        int i = find_opt(p, opt);

        if (i < 0) {
            fprintf(stderr, "Unknown option %s\n", p);
            exit(1);
        }

        res |= (1u << i);

        p = strtok(NULL, ",");
    }

    return res;
}

int main()
{
    const char *opt[] = {
        "knn", "lda", "lr", "kart", "nb", "svm", NULL
    };
    char *msg = " knn, lda, svm ";
    unsigned int u;
    int i;

    u = multi_opt(msg,opt);

    for (i = 0; opt[i]; i++) {
        printf("%s: %s\n", opt[i], (u & 1u << i) ? "on" : "off");
    }

    return 0;
}

You can try with the strtok() function:您可以尝试使用strtok()函数:

char *token;

token = strtok(optarg, ",");
while (token != NULL)
{
    if (!strcmp(token, "knn") && !strcmp(token, "lr") && !strcmp(token, "la")
        *error handling*
    token = strtok(NULL, ",");
}

PS: strtok() is part of string.h PS: strtok()string.h的一部分

EDIT: I don't think this code will have your desired behaviour.编辑:我认为这段代码不会有你想要的行为。 This will be better:这会更好:

char *token;
size_t i = 0;
char knn = 0, lr = 0, la = 0;

token = strtok(optarg, ",");
while (token != NULL)
{
    if (!strcmp(token, "knn") && knn == 0)
        knn = 1;
        ... // valid
    else if (!strcmp(token, "lr") && lr == 0)
        lr = 1;
        ... // valid
    else if (!strcmp(token, "la") && la == 0)
        la = 1;
        ... // valid
    else
    {
        printf("Wrong value entered for option -a\n");
        exit();
    }
    token = strtok(NULL, ",");
    i++;
}

if (i > 3)
{
    printf("Too many values entered for option -a\n");
    exit();
}
          char *alg,alg1;

       case 'a' :
                 flaga=1;
                 alg = optarg;
                 printf("1. you entered option -a \"%s\"\n", alg);

This printf o/p :1.这个 printf o/p :1。 you entered option -a "svm,lr"你输入了选项 -a "svm,lr"

                 alg1 = strtok(optarg, ",");
                 while (alg1 != NULL)
                     {
                      if(strcmp(alg1,"lr") == 0 )
                           {
                              //valid
                            }
                         '""""""
                         '"""""""
                      else
                          {
                          }
                      alg1 = strtok(NULL, ",");
                      j++;
                   }
                 printf("2.you entered option -a \"%s\"\n", alg);

This printf o/p :2.这个 printf o/p :2。 you entered option -a "svm" But expected : svm,lr您输入了选项 -a "svm" 但预期:svm,lr

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM