Search code examples
cfile-iocommand-linegetopt

Segmentation fault when using command line arguments


I am trying to get the input and output file names through command line arguments. I am just using getopt (tell me if there is a better way) and I got segmentation fault

I am sure that the segmentation fault is caused by the name of the input file. Some thing is going wrong when I take the name of the input file from the command line.

Here is my code:

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

    char const *inFile = NULL; //I think the error is here
                               //an inFile that doesn't exist
                               //would cause a segmentation fault
    char const *outFile = "outfile.txt";
    double val;
    int xFlg= 0;
    int c;
    char *rm; //I need this for strtod, but I can use atoi instead

    while ( (c = getopt (argc, argv, "xo")) != -1 ) {
        switch (c) {
            case 'x':
                val = strtod(optarg, &rm);
                xFlg = 1;
                break;
            case 'o':
                outFile = optarg;
                break;
            default:
                help(); //void function that prints help
                return EXIT_FAILURE;
        }
        rm=NULL;
    }
    inFile = *(argv + optind);

    fread code
    .
    .
    .
    call function
    .
    .
    .
    fwrite code
}

I am sure that there is no problem with my freads and fwrites because if I take the name of inFile and outFile using scanf, everything works perfectly and I don't get a segmentation error.

I am using the value of xflg to decide whether to run my function or not. val is the value that my function takes.

Here is my function:

void xFunc (input1, input2, val, xFlg) {
    if (xFlg == 1) {
        function code
        .
        .
        .
    } else {
    return; //don't run the function if the user doesn't type -x
            //into command line.
            //I don't know if this is the proper way to do this.
    }
}

This is what I want to achieve:

./run -x 3.14 -o outputfilename.txt inputfilename.txt

Edit:

If I do the following to get the input file name, no segmentation fault happens:

char inFile[100];
printf("Name of input file: \n");
scanf("%99s",somestring);

Solution

  • the problem is two fold:

    char const *inFile = NULL;
    ......
    inFile = *(argv + optind);
    

    Once you initialized a const char* you cannot assign it another value. So to fix this you can try one of the following:

    .....
     char const * inFile = *(argv + optind);
    .....
    

    If you don't need the inFile pointer up to the point where you initialize it this should be fine.

    OR

    char inFile[20]; //whatever size you need
    ......
    strcpy(inFile, *(argv + optind));
    

    This way you can change the file pointer, if you need to