strcpy and assignment does not work

I am modifying a program to accept command line parameters and I have two tables called "trades" and "quotes". I want to read these from the command line and assign them to
variable table1 and table2. For some reason, the assign does not work properly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
  #include <unistd.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <errno.h>
  #include "k.h"

  #define KXVER 3

  static const char *optString="t::";


  int main(int argc, char *argv[]){
    int opt=0;
    char table1[30];
    char table2[30];

    printf("%s and %s\n",argv[2],argv[3]);//this one prints ok

    opt=getopt(argc,argv,optString);
    while(opt!=-1){
      switch(opt){
        case 't':
          strcpy(table1,argv[2]);
          strcpy(table2,argv[3]);
          printf("%s and %s\n",table1,table2);//this one prints garbage
        default:
          printf("default case\n");
          return 1;
      }
    opt=getopt(argc,argv,optString);
    }
  printf("table 1 is %s and table 2 is %s\n", table1, table2);

  return 0;
  }
Shouldn't the command-line arguments be argv[1] and argv[2]?

printf("%s and %s\n",argv[2],argv[3]);

-> this line would have also failed. I think argv[0] is the name of the program, argv[1] is the flag and argv[2] and argv[3] are the tables. However I do not know if this is a valid assign with the getopt function.
Last edited on
What flag? You don't say anything in your OP about passing in a flag as well. Certainly, there's nothing in your code that references argv[1], so whatever you're passing in as the first argument is not being used anywhere.
Looking at the linux manual for getopt at http://man7.org/linux/man-pages/man3/getopt.3.html , and also looking at an example https://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html .

1. Why not have line 10 with a with a single colon?
Two colons mean an option takes an optional arg; if there is
text in the current argv-element (i.e., in the same word as the
option name itself, for example, "-oarg"), then it is returned in
optarg, otherwise optarg is set to zero. This is a GNU extension.


The double colon appears to invite complications.

2. We can see that the option flag is the output of getopt, "opt" in your case, which is fine. You forgot to make use of the special variable optarg . See the example for reference. I also suspect your input may have spaces, which obviously messes w/ argument parsing altogether.

3. Missing break in your cases. Always break each case unless you intentionally want stuff to fall through.

4. I suggest to just make a second option for the second table, since you're into getopt anyway.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 #include <unistd.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <errno.h>
  #include "k.h"

  #define KXVER 3

  static const char *optString="tu:";

  int main(int argc, char *argv[]){
    int opt;
    char table1[30];  // t option
    char table2[30];  // u option

    // Variables to make sure both flags are specified
    int tflag = 0;
    int uflag = 0;  
    
    while( (opt=getopt(argc,argv,optString)) !=-1){
      switch(opt){
        case 't':
          tflag = 1;
          strcpy(table1, optarg);
          break;

        case 'u':
          uflag = 1;
          strcpy(table2, optarg);
          break;   

        default:
          printf("Usage:  myprogram -t <table1> -u <table2>\n");
          return 0;
      }
    }
  if (!tflag && !uflag)
  {
      printf("Both -t and -u options are required\n");
      return 2;
  }

  printf("table 1 is %s and table 2 is %s\n", table1, table2);

  return 0;
}



See also (from the example) how they check for bad arguments with the special variable optind, which auto-updates with getopt. They have a for loop to cycle through anything else the user might have (erroneously) added and prints out the issue "Non-argument ...".
Last edited on
So if I expect someone to execute the program -> ./<progName> -t table1 table2 shouldn't I have the flag and two potential options? What if I don't know how many tables the user wants? What if the user wants something like ./<progName> table1 table2 table3 table4 table5 ... tableN where each table has a name that I do not know beforehand, but if passed by user in the correct form I can extract it from a database? Any chance you could point me in the right direction for achieving that? Thanks!
Registered users can post here. Sign in or register to post.