3

So, I noticed that my argc is always 1 as I will always get the message Error: missing command line arguments!, but as stated in code I am using argv[1] and argv[2] to read the files names.

Shouldn't automatically argc be 3 in this case, and to be able to pass that error?

Notes:

  1. If I am not using if (argc < 2) statement, after I enter the name for the output file my program crushes.
  2. For the input file I already have this one created in the project folder, so I just enter the name of that file.

This is the code:

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

FILE *IN, *OUT;

int main(int argc, char* argv[])
{
    if (argc < 2) 
    {
        printf("Error: missing command line arguments!\n");
        return 1;
    }

    printf("Enter the name of the file with the input data: ");
    scanf("%s", argv[1]);

    printf("\nEnter the name of the file for the output data: ");
    scanf("%s", argv[2]);

    IN = fopen(argv[1], "r");
    OUT = fopen(argv[2], "w");  

    fclose(IN);
    fclose(OUT);

    return 0;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
ISimion
  • 108
  • 8
  • 3
    How do you invoke your program? It's actually quite a crucial detail if you have problems with the programs arguments... – StoryTeller - Unslander Monica Mar 12 '17 at 14:35
  • Is `argv` read only? – Ed Heal Mar 12 '17 at 14:36
  • It seems like you have completely misunderstood what command line arguments are. You should not write to argv. It is a string array for the input arguments. Here is an example of how to use argc and argv: http://www.thegeekstuff.com/2013/01/c-argc-argv/ – klutt Mar 12 '17 at 14:38
  • 2
    @EdHeal - [It's perfectly fine to modify those arguments](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p2), so long as the pointed-to memory is valid of course. – StoryTeller - Unslander Monica Mar 12 '17 at 14:39
  • 1
    @EdHeal You can write to argv, but I cannot think of any good reason to do it. – klutt Mar 12 '17 at 14:41
  • Thank you, guys, all your questions and suggestions set me to do some more research and found a solution. I explained it all below in my comment to the answer of @Sourav Gosh. – ISimion Mar 12 '17 at 15:40

1 Answers1

9

You're complete mis-understanding the purpose of argc and argv. They are supposed to receive the supplied command line argument (program parameters) before the program startup, not supposed to hold the scannned input at runtime.

Quoting C11, chapter §5.1.2.2.1,

If they are declared, the parameters to the main function shall obey the following constraints:

— The value of argc shall be nonnegative.

argv[argc] shall be a null pointer.

— If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment.

and

If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.

To elaborate, when a program is invoked like

./a.out three total arguments

then, in your program

  • argc will be 4
  • argv[0] will be ./a.out
  • argv[1] will be three
  • argv[2] will be total
  • argv[3] will be arguments
  • argv[4] will be NULL (see the property for argv[argc] above)

(To generalize, argv[1] - argv[argc-1] will hold the supplied arguments, argv[argc] will be NULL)

You don't need to explicitly scan the input, those values will be populated from the host environment.

On the other hand, you cannot just invoke the program like

./a.out

and exptect argc to be 3 (or any other value, other than 1, for that matter) and argv[1] - argv[n-1] to be valid because at compile-time the invokes program has no way to know that you plan to supply some values at runtime. It's not clairvoyant.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Thanks, it was really helpful for understanding how `argc` and `argv` works. I've done some more research and found a solution. I run the program in Code::Blocks 16.01, and found how to set the arguments for a file reading, or anything else for the matter. – ISimion Mar 12 '17 at 15:34
  • For those interested of how to set arguments in Code::Blocks 16.01, you have to go in Project->Set Program Arguments. At Debug, in the text box named Program Arguments, one writes the arguments he wants to set to, knowing that the first argument written will coincide with `argv[1]`, since `argv[0]` is the source location of the program's executable. – ISimion Mar 12 '17 at 15:46