1

I have a dynamically allocated array with an allowable tokens. After each token user should write a number, which will be used to define a variable's value [$ program --token=99]; how to parse this last number?

Here is code:

/* libs */

#define TOKENS_QT 5
#define TOKEN_SIZE 6

static uint8_t GRID_WIDTH;

int main (const int argc, const char* argv[]) {
  if (strncmp(argv[1], "--help", 6)) {
    /* Here is some info about usage. */
    return 0;
  } else if (strncmp(argv[1], "--std", 5)) {
    /* Here is standard set up. */
  } else if (argc == TOKENS_QT + 1) {
    char** tokens = malloc(TOKENS_QT * TOKEN_SIZE);
    tokens = (char* [TOKENS_QT]) { "--sgw=", "--sgh=", "--sdq=", 
                                   "--shq=", "--soq=" };

    for (register uint8_t i = 0; i < TOKENS_QT; ++i) {
      if (strncmp(argv[i + 1], tokens[i], 6)) {
        switch(i) {
          case 0: // --sgw=
            /* some cool actions to parse --sgw=99, for example, into 99 */
            /* some actions to check validity of given number */
            GRID_WIDTH = 99;
            break;
          /* There are other tokens handling. */
        }
      }
    }

    free(tokens);
  } else {
    /* Here is again info about correct usage. */
    return 0;
  }

  return 0;
}
  • 1
    Those look like command line options. The standard way to parse them is by use of getopt_long(3) as [answered here](https://stackoverflow.com/questions/7489093/getopt-long-proper-way-to-use-it). You probably wouldn't want to re-invent the wheel. – Tano Fotang Oct 05 '18 at 22:22
  • 1
    Don't use the `register` declaration; see https://stackoverflow.com/questions/314994/whats-a-good-example-of-register-variable-usage-in-c – Barmar Oct 05 '18 at 22:30
  • @TanoFotang Should I delete this question then? –  Oct 05 '18 at 22:30
  • @Barmar why? This is proper `register` usage, isn't it? –  Oct 05 '18 at 22:31
  • @GlebWernher I am not sure. Someone else might have the same question tomorrow and your question would be useful. I am new here. – Tano Fotang Oct 05 '18 at 22:32
  • @GlebWernher It's not needed, modern compilers are much better than programmers at determining which variables should be in registers. Read the question I linked to. – Barmar Oct 05 '18 at 22:33
  • @Barmar It's hard to accept the thing, that's compiler smarter than I. –  Oct 05 '18 at 22:34
  • @Barmar btw, is there way to make compiler respect my wishes? –  Oct 05 '18 at 22:36
  • If you want direct control of the generated code, write in assembly. – Barmar Oct 05 '18 at 22:37
  • @Barmar I'm not crazy enough to do it :) –  Oct 05 '18 at 22:39

1 Answers1

0

You can use sscanf() to parse it.

sscanf(argv[i + 1], "--sgw=%d", &GRID_WIDTH);

If you don't want to put --sgw= in the format string, you can do:

sscanf(argv[i+1]+6, "%d", &GRID_WIDTH);

Adding 6 skips past the --sgw= prefix in the argument.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Can I use it like this: `sscanf(argv[i + 1], tokens[i], %GRID_WIDTH);`, if I will write my tokens like `"--sgw=%d"`? –  Oct 05 '18 at 22:42
  • No, you can't. The second argument to `sscanf()` has to be a format string, with `%d` in it to indicate where to parse an integer. `tokens[i]` doesn't have `%d` in it. And what is `%GRID_WIDTH` supposed to mean, was that a typo for `&GRID_WIDTH`? – Barmar Oct 05 '18 at 22:48
  • Yes, this was a typo. I meant I would wrote `tokens` like `{ "-t=%d", "-a=%d" /* etc */ }`. –  Oct 05 '18 at 22:56
  • Anyway you supposed a better way with `argv[i + 1] + 6`, so I will use it. –  Oct 05 '18 at 22:58
  • @gleb: There's a lot to be said for using `strtoul` instead of `sscanf` here. Much better error checking, for example. Re `register`: it's deprecated and will at some point be removed or repurposed. Current compilers pretty well ignore it. – rici Oct 06 '18 at 03:34
  • @rici so it's bad practice to use keywords like `register`, `inline`, etc? –  Oct 06 '18 at 05:07
  • @gleb inline has a meaning. It's just not precisely the meaning the name would suggest; it has more to do with linking. If you know what it means and want what it provides, its use is just fine. – rici Oct 06 '18 at 06:38
  • @GlebWernher Both of them started out as hints to the compiler to improve optimization, but compiler technology has gotten much better and they don't need the help any more. `register` is essentially useless now, `inline` is retained for the linking effect that was a consequence of the original meaning. – Barmar Oct 07 '18 at 01:01