C/C++ Arena

Step 5 of 7

Command-line arguments

Command-line programs receive input as arguments: the words typed after the program's name, like gcc -Wall main.c or git commit -m "fix". To receive them, declare main with two parameters:

int main(int argc, char **argv)

So running ./sum 4 5 6 gives argc == 4, argv[1] is "4", and argv[3] is "6". They're always strings, even when they look like numbers.

Converting to numbers safely

atoi("12abc") returns 12 and atoi("abc") returns 0 with no way to tell something went wrong. strtol reports where it stopped:

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

int parse_int(const char *s, long *out) {
    char *end;
    long v = strtol(s, &end, 10);
    if (end == s || *end != '\0') {
        return 0;
    }
    *out = v;
    return 1;
}

int main(void) {
    const char *tests[] = {"42", "-7", "12abc", ""};
    for (int i = 0; i < 4; i++) {
        long v;
        if (parse_int(tests[i], &v)) printf("\"%s\" -> %ld\n", tests[i], v);
        else printf("\"%s\" is not a number\n", tests[i]);
    }
    return 0;
}
"42" -> 42
"-7" -> -7
"12abc" is not a number
"" is not a number

After the call, end points at the first character strtol didn't use. If it's the start of the string, no digits were found; if it's not the terminator, junk followed the number. Only when it's at the '\0' was the whole argument a clean number.

(The example tests fixed strings; in your program, loop over argv[1] to argv[argc - 1].)

Your turn: print the sum of all arguments. If any argument isn't a clean integer, print bad number: ARG and stop. The tests run your program with different arguments.

Previous: const-correct interfaces Next: Variadic functions