Search code examples
ccommand-line-argumentsfopengetopt

Program isn't creating file using name specified on the command line


For this program I am supposed to either write my name to the terminal or to the output file given by the user(case 'f').

#include <stdio.h>

int main(int argc, char **argv)
{
    // no output file print to screen, print name to terminal
    if (argc < 2)
    {
        fprintf(stdout, "name\n");
    }
    //print name to output file given by user
    else
    {
        int option;
        int fFlag = 0;
        while ((option = getopt(argc, argv, "f:")) != -1)
        {
            //if case 'f' print to output file
            switch (option)
            {
                case 'f':
                    fFlag = 1;  // flag indicates writing name to file
                    break;
                    //case f or error
                case '?':
                    printf("error");
                    break;
            }
        }
        //write to name to output file
        if (fFlag)
        {
            FILE *file = fopen(argv[1], "w");
            fprintf(file, "name");
        }
    }
    return 0;
}

My code works when I want to write my name to the terminal, but it doesn't work when I want to write my name to the file given by the user. The code compiles and runs, but the file just doesn't exist.

The file in the command line might not already exist. Am I supposed to create the file in the program?

I understand what I was doing wrong. Thank you to everyone!


Solution

  • In addition to what the commenters have said, you are using getopt for part of your parsing so should use it for the rest!

    int main...
    char *filename;    /**1**/
    ...
      case 'f': 
        fFlag = 1;
        filename = optarg;  /**2**/
    ....
      FILE *file = fopen(filename , "w");  /**3**/
    

    Explanation: the f: to getopt means that getopt is going to try to find the option that goes along with the f. In the getopt loop, case 'f', that option is put in the variable optarg. At least for GNU getopt, that is a pointer into argv, so you don't have to copy it. You can just stash its pointer value (at *2* above) into a variable you have created for the purpose (*1*). Then you can open that particular file without regard to where it is in argv (*3*). See the treatment of option c in the GNU getopt example.

    Edit You haven't shown the command line you're using, but I am guessing it's something like

    ./foo -f my-output-file.txt
    

    — in which case argv[1] is -f and argv[2] is my-output-file.txt. (argv[0] is the name of your executable.) Hence fopen(argv[1], ...) is not what you want ;) .