Search code examples
cparsingvariablesargvargc

C - Assigning value of argv to a variable


I am parsing the name of my .txt file as a parameter into the command line when calling the program. I want to assign the .txt file's name to a char variable.

enter image description here

Here is my attempt:

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

int main(int argc, char **argv[])
{
    int i;
    for (i=0; i < argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);

    FILE *fPointer;
    if ((fPointer = fopen("exampleWheel.txt", "r")) == NULL) {
        fprintf(stderr, "can't open file");
        exit(1);
    }

    return 0;
}

In line 11, I want to replace the string "exampleWheel.txt" with the value of argv[ 1 ] so that I can open any .txt file.

Please show me how I can apply this to my existing code.

Thank you in advance :)


Solution

  • Your initial problem is here:

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

    char **argv[] is wrong. It's either char *argv[] or char **argv

    You have one too many levels of indirection for argv. See: C11 Standard - §5.1.2.2.1 Program startup(p1). Your compiler should be screaming warnings at you...

    You do have warnings enabled right? -Wall -Wextra -pedantic for gcc/clang or /W3 for VS. I suspect after you fix the invocation for main and make the replacement you want -- all will work correctly.

    Since you are wanting to pass the filename as an argument to main() (which is the proper way to do it), you also need to ensure the user provide all required arguments before passing argv[1] to fopen. You can do this with a simple if (argc < 2) check to check you have at least 2 arguments provided to the program.

    Incorporating the check, you could do:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        FILE *fPointer;
    
        if (argc < 2) { /* validate required arguments provided */
            fprintf (stderr, "error: insufficient input.\n"
                             "usage: %s <filename>\n", argv[0]);
            return 1;
        }
    
        if ((fPointer = fopen (argv[1], "r")) == NULL) {
            perror("fopen-argv[1]");       /* a fopen failure sets errno, use perror */
            exit (EXIT_FAILURE);
        }
    
        return 0;
    }
    

    Note above that on failure the fopen function sets errno which allows you to output the system error using the perror() function. You can use that in addition to, or in lieu of your fprintf message. When you include stdlib.h you have the system macros defined for EXIT_SUCCESS (value is 0) and EXIT_FAILURE (value is 1), you can use instead of hardcoding exit(1);. Up to you.