Search code examples
ccommand-lineprogram-entry-point

Unexpected result when parsing argument in main function in C


I have really simple code to understand command line arguments parsing of main in C language:

#include <stdio.h>

int main(int argc, char* argv[]){

for(int i=1; i < argc; i++)
printf("%d\n", argv[i]);

printf("Number of arguments: %d\n", argc);

}

Having compiled and executed in a terminal passing 3 integers (eg. 1, 2, 3), I obtain the following strange result:

1175842993
1175842995
1175842997
Number of arguments: 4

I know that the solution is lying right straightforwardly towards my eyes, but it's been a hour that I cannot actual figure it out! Any hints? Thanks!


Solution

  • Dereference your pointer:

    printf("%d\n", *argv[i]);
    

    You may also be a little surprised, as you will get a numerical value represented by the (first) character printed; for instance for 1 it is 49.

    In general you can tell your compiler to tell you a bit more by enabling more warnings. For instance gcc -Wall would tell you:

    warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘char *’ [-Wformat=] printf("%d\n", argv[i]);

    Which would actually be a pretty solid hint.

    And a side note: if you declare your main as int, you should return one too. ;) (But see EDIT2 for details).


    EDIT: I guess I should have mentioned that with the actual output surprise in the second paragraph.

    If verbatim reprint of the argument(s) is what you actually wanted. You'd use %s in your formatting string as Jonathan Leffler pointed out in the comment. In that case, you want the argument passed to be pointer to a string again (i.e. you do not use the * dereference operator).


    EDIT2: As pointed out by Antti Haapala regarding the closing "Side note".

    When using C99 or C11 you do not have to explicitly return (a value) for your main (and we're talking about main) that has been declared to return int. In that case default of 0 will be assumed. You really only need to do that for when adhering to C89 standard or other functions. For sake of simplicity though and/or when not sure what your target compiler configuration is, you won't be wrong being (type) consistent between your declared and actually returned value type. And again. gcc -Wall for example would let you know about that.