2

I need to give default behavior to a command line app if no arguments are entered.

If no arguments are entered, I need the program to set argv[1][0] = '1' and argv[1][1] = '\0' for the null terminator.

I keep getting a core dump when I try to compile my code in g++, and here is what is causing the issue:

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


    //for testing we put some dummy arguments into argv and manually set argc
    //argc = 1;//to inlcude the program name 

    //we put a defualt value into argv if none was entered at runtime
    if(argc == 1){
        argv[1][0] = '1';
        argv[1][1] = '\0';//add a null terminator to our argv argument, so it can be used with the atoi function
    }

Also, I am not on C++ 11.

RE-FACTORED CODE: (Which basically just codes around the issue so that we don't have to manipulate argv[] in the main function)

int argvOneAsInt;
        if(argc != 1){
            argvOneAsInt = atoi(argv[1]);//use atoi to convert the c-string at argv[1] to an integer
        }
        else{
            argvOneAsInt = 1;
  • You should copy the arguments to variables and use those in your program. Then it's easy to set your variables if the arguments aren't supplied. – sje397 Nov 16 '14 at 03:56
  • If no arguments are provided, then what do you think `argv[1]` points to? Tip `std::vector args(argv, argv + argc);` now you can do what you want with it. – Neil Kirk Nov 16 '14 at 03:57
  • You need to make a copy of `argv`. This will allow you to use default values. So, make your local `argv` variable with default values, then copy the `argv` values from `main` parameters into your local `argv` variable. – Thomas Matthews Nov 16 '14 at 04:12

3 Answers3

4

If argc equals 1, then the second value in the array argv is NULL. You are dereferencing that NULL pointer right here:

argv[1][0] = '1';

Instead of trying to manipulate argv, rather change the logic in the code. Use an array you control in memory, copy argv to it and then manipulate the array.

2501
  • 25,460
  • 4
  • 47
  • 87
  • Are you sure it is null and not undefined? – Neil Kirk Nov 16 '14 at 03:58
  • @NeilKirk Yes `argv[argc]` is NULL, and you get ub trying to dereference it. What a ridiculous downvote... – 2501 Nov 16 '14 at 03:58
  • I can definitely change my logic, but I would also like to know how to properly add char values to argv if I need too. –  Nov 16 '14 at 03:59
  • Interesting, I checked on two compilers and it is indeed null! I didn't know that. – Neil Kirk Nov 16 '14 at 04:01
  • @NeilKirk, Standard N3337 § 3.6.1 [basic.start.main]: _"The value of argv[argc] shall be 0. [Note: It is recommended that any further (optional) parameters be added after argv. —end note ]"_ – awesoon Nov 16 '14 at 04:03
  • @soon Thanks Soon, although I don't understand the note. – Neil Kirk Nov 16 '14 at 04:04
  • Well 2501, you didn't actually tell me how to fill argv to get what I needed from it, but I coded around it in a much cleaner fashion in my code, and I think your idea to do so was for the best. Although, if you do know how I could succesfully manipulate argv in this case, I would appreciate it. I will accept your answer either way though –  Nov 16 '14 at 04:07
  • 1. None of your business. 2. No. – Neil Kirk Nov 16 '14 at 04:09
  • @NeilKirk, I guess the Standard defines the way of extending `main` signature on some platforms. For example, under Linux you could use `int main(int argc, char *argv[], char *envp[])` in order to get the environment variables. – awesoon Nov 16 '14 at 04:18
  • Thanks again @2501, I have posted my re-factored code that just bypasses the issue altogether. –  Nov 16 '14 at 16:38
0

This all looks rather dodgy. I would probably do something like this:

int main(int argc, char* argv[])
{
    std::string arg1 = "1"; // set default

    if(argc > 1) // override default if present
        arg1 = argv[1];

    // Now use arg1 and forget about argv[]
}
Galik
  • 47,303
  • 4
  • 80
  • 117
-1

just to support your question, what ever you wanted was not faulty but you forgot to allocate memory where you wanted to assign your values.
Check this:

#include <string.h>
#include <malloc.h>

using namespace std;

int main(int argc, char * argv[]){
    //for testing we put some dummy arguments into argv and manually set argc
    //argc = 1;//to inlcude the program name 

    //we put a defualt value into argv if none was entered at runtime
    if(argc == 1){
        argv[1] = (char*)malloc(strlen("1\0"));
        argv[1][0] = '1';
        argv[1][1] = '\0';
        //argv[1][2] = '\0';
        //argv[1] = '\0';//add a null terminator to our argv argument, so it can be used with the atoi function
    }
}

now it should work the way you want.

Rupesh Yadav.
  • 894
  • 2
  • 10
  • 24
  • What if there is more than one additional parameter? – Neil Kirk Nov 16 '14 at 04:44
  • i think the most important point should be to make OPs clear that why his program is not working. And if OPs is asking something which is illogical or not possible then we can give some other ways to accomplish his task. @NeilKirk its obvious there are always some different ways. – Rupesh Yadav. Nov 16 '14 at 05:03