Search code examples
ccommand-linestrtokgetoptstrtod

Separate 9 numbers of type double from command-line in c with strtok() and strtod()


I have the following command-line interface with a -k parameter that looks like this: -k "0.0:-1.0:0.0:-1.0:4.0:-1.0:0.0:-1.0:0.0". These are 9 double values separated by ":". I've managed to separate the first double value 0.0 with strtok() and strtod() but I need all 9 values and I don't seem to find an efficient way to do it.

Maybe with a loop and then save the values in a 2x3 array but no results yet. In the end, I have to use these numbers to manipulate pixels in an image. Note that these are example numbers and the user can type any double value from 0 to let's say 255. Hope someone can help with some advice.

Below is the code on how I managed to separate the first value. I would appreciate any advice on how to solve this, thank you!

char *kernel_input; 
char *end = NULL;
kernel_input = strtok(kArg, ":");

if(kernel_input == 0)
{
  /* ERROR */
}

double value_1 = (double) strtod(kernel_input, &end);

Solution

  • Would you please try something like:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define ARYSIZE 100                     // mamimum number of elements
    
    /*
     * show usage
     */
    void
    usage(char *cmd)
    {
        fprintf(stderr, "usage: %s -k value1:value2:..\n", cmd);
    }
    
    /*
     * split str, store the values in ary, then return the number of elements
     */
    int
    parsearg(double *ary, char *str)
    {
        char *tk;                           // each token
        char *err;                          // invalid character in str
        char delim[] = ":";                 // the delimiter
        double d;                           // double value of the token
        int n = 0;                          // counter of the elements
    
        tk = strtok(str, delim);            // the first call to strtok()
        while (tk != NULL) {                // loop over the tokens
            d = strtod(tk, &err);           // extract the double value
            if (*err != '\0') {             // *err should be a NUL character
                fprintf(stderr, "Illegal character: %c\n", *err);
                exit(1);
            } else if (n >= ARYSIZE) {      // #tokens exceeds the array
                fprintf(stderr, "Buffer overflow (#elements should be <= %d)\n", ARYSIZE);
                exit(1);
            } else {
                ary[n++] = d;               // store the value in the array
            }
            tk = strtok(NULL, delim);       // get the next token (if any)
        }
        return n;                           // return the number of elements
    }
    
    int
    main(int argc, char *argv[])
    {
        int i, n;
        double ary[ARYSIZE];
    
        if (argc != 3 || strcmp(argv[1], "-k") != 0) {
                                            // validate the argument list
            usage(argv[0]);
            exit(1);
        }
    
        n = parsearg(ary, argv[2]);         // split the string into ary
    
        for (i = 0; i < n; i++) {           // see the results
            printf("[%d] = %f\n", i, ary[i]);
        }
    }
    

    If you execute the compiled command e.g.:

    ./a.out -k "0.0:-1.0:0.0:-1.0:4.0:-1.0:0.0:-1.0:0.0"
    

    It will output:

    [0] = 0.000000
    [1] = -1.000000
    [2] = 0.000000
    [3] = -1.000000
    [4] = 4.000000
    [5] = -1.000000
    [6] = 0.000000
    [7] = -1.000000
    [8] = 0.000000
    

    If you put an invalid charcter in the string, the program will print an error message and abort.