Home > other >  Working with base for strtol argument in C
Working with base for strtol argument in C

Time:11-24

I've been learning C by using some book and there's some code that I don't understand regarding working with base in C programming. So, here's the code:

/* By default, integers are decimal */
#define GN_ANY_BASE 0100 /* Can use any base - like strtol(3) */
#define GN_BASE_8   0200 /* Value is expressed in octal */
#define GN_BASE_16  0400 /* Value is expressed in hexadecimal */

// rlength: Read length bytes from the file, starting at the current file offset, and display them in text form.
int main(int argc, char *argv[]) {
    fd = open(argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); /* rw-rw-rw- */
    if (fd == -1)
        errExit("open");
    for (ap = 2; ap < argc; ap  ) {
        switch (argv[ap][0]) {
          case 'r': /* Display bytes at current offset, as text */
          case 'R': /* Display bytes at current offset, in hex */
            len = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]);
            buf = malloc(len);
            ...
}

And here's the getLong function:

long getLong(const char *arg, int flags, const char *name) {
    return getNum("getLong", arg, flags, name);
}

And here's the getNum function:

static long getNum(const char *fname, const char *arg, int flags, const char *name) {
    long res;
    char *endptr;
    int base;

    if (arg == NULL || *arg == '\n') 
        gnFail(fname, "null or empty string", arg, name);

    base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8 : (flags & GN_BASE_16) ? 16 : 10;
    res = strtol(arg, &endptr, base);

    return res;
}

This line really confuses me, and what happened after that didn't help either:

base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8 : (flags & GN_BASE_16) ? 16 : 10;

What did it do? and why do we need this? what is GN_BASE ?

I can run the programs from the terminal by using the command:

./main file.txt r50

And it will give the following output like this:

r50: this is a text inside file.txt

I tried removing as many codes as possible for this example and hope it helps clear the example.

I'm sorry for asking beforehand. Thank you very much.

CodePudding user response:

  1. The argument flag can carry other information so we mask what we are interested in with bitwise and-operator (&). Btw, often those mutually exclusive flags are written with a left shift instead of absolute values (1<<6, 1<<7, 1<<8).
  2. We map the value provided to something that is more convenient for use internally (0100 to 0, 0200 to 8, and 0400 to 16).
  3. Finally, we provide a default value of 10 if none of those 3 base bits were found.
  • Related