argv Value Swapping

Discussion in 'C Programming' started by Matt, Jul 25, 2007.

  1. Matt

    Matt Guest

    Hello. This should hopefully be a quick question!

    I have a programme given below which deals with any arguments given to
    the programme by the user (see a previous post titled "Problem
    Outputting Command Line Arguments from argv" to see my previous
    problems with this programme).

    Basically for some reason the programme is swapping round the values
    of argv[1] and argv[2] with argv[3] and argv[4]. I've made the
    programme output this to illustrate what I mean:

    "> ./main.exe file1 file2 -c '/dir1/dir2/default_config'
    ----Before getopt_long function----
    argc = 5
    argv[0] = ./main.exe
    argv[1] = file1
    argv[2] = file2
    argv[3] = -c
    argv[4] = /dir1/dir2/default_config
    option -c with value `/dir1/dir2/default_config'
    non-option ARGV-elements: file1 file2
    ----After getopt_long function----
    Count = 2
    argc = 5
    argv[0] = ./main.exe
    argv[1] = -c
    argv[2] = /dir1/dir2/default_config
    argv[3] = file1
    argv[4] = file2
    Stack mode OFF"

    I believed the problem was caused by the area from line 124 where I
    get the programme to read all "non-relevant" arguments given to the
    programme by the user. However my attempt to undo any changes made to
    where the pointer is located on line 135 don't seem to have made any
    difference.

    Any help anyone can offer will be much appreciated.

    Kind Regards,

    Matt
     
    Matt, Jul 25, 2007
    #1
    1. Advertisements

  2. Matt

    Matt Guest

    Sorry, here's the code :)

    // Main function for the subtract algorithm

    // Load function libraries
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h>
    #include <fitsio.h>
    #include <time.h>
    #include <getopt.h> // NEW CODE
    #include <ctype.h> // NEW CODE

    #include "image.h"
    #include "functions.h"
    //$$$$$$ #include "vectors.h"

    static int stack_mode;

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

    {

    // Declare variables and constants
    int getopt_val;
    int count = 0;
    int i; // DO loop parameter
    char config_file[256];

    // Process command line options and config files
    sprintf( config_file , "default_config" ); // Write to config_file
    string

    // Read all command line arguements

    /* Before getopt_long function */

    printf("----Before getopt_long function----\n");

    printf("argc = %d\n",argc);

    for ( i = 0 ; i < argc ; i++ )

    {

    printf("argv[%d] = %s\n",i,argv);

    }

    while (1)

    {

    static struct option long_options[] =

    {

    // These options set a flag.
    {"stack" , no_argument , &stack_mode , 1}, // Enable stack
    (convolution) mode

    // These options don't set a flag. We distinguish them by their
    indices.
    {"configfile" , required_argument , 0 , 'c'},

    {0 , 0 , 0 , 0}

    };

    // getopt_long stores the option index here.
    int option_index = 0;

    getopt_val = getopt_long (argc, argv, "c:", long_options,
    &option_index);

    // Detect the end of the options.
    if (getopt_val == -1)

    {

    break;

    }

    switch (getopt_val)

    {

    case 0:
    /* If this option set a flag, do nothing else now. */
    if ( long_options[option_index].flag != 0)

    {

    break;

    }

    printf ("option %s", long_options[option_index].name);

    if (optarg)

    {

    printf (" with arg %s", optarg);

    }

    printf ("\n");
    break;

    case 'c':
    printf ("option -c with value `%s'\n", optarg);
    sprintf( config_file , "%s" , optarg );
    break;

    case '?':
    /* getopt_long already printed an error message. */
    break;

    default:
    abort ();

    }

    }

    /* After getopt_long function */

    printf("----After getopt_long function 1----\n");

    printf("Count = %d\n",count);
    printf("argc = %d\n",argc);

    for ( i = 0 ; i < argc ; i++ )

    {

    printf("argv[%d] = %s\n",i,argv);

    }

    /* Print any remaining command line arguments (not options). */
    if (optind < argc)

    {

    printf ("non-option ARGV-elements: ");

    while ((optind + count) < argc)

    {

    count++;
    printf ("%s ", argv[optind + count - 1]);

    }

    printf("\n");

    }

    if (stack_mode)

    {

    printf ("Stack mode ON\n");

    }

    else

    {

    printf ("Stack mode OFF\n");

    }

    return 0;

    }
     
    Matt, Jul 25, 2007
    #2
    1. Advertisements

  3. Matt

    Matt Guest

    Anyway, I just realised I could output the argv values earlier to see
    where the change happens. Having just output the values before the
    suspect bit of code, the swap is still occurring, so my original
    suspicions are clearly incorrect!

    Kind Regards,

    Matt
     
    Matt, Jul 25, 2007
    #3
  4. Matt

    Matt Guest

    Ok the swap seems to occur on the second pass of the following line:

    getopt_val = getopt_long (argc, argv, "c:", long_options,
    &option_index);

    which is the key part of this programme as this is where the arguments
    are read. The getopt_long function is described here:

    http://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html

    which can be found by putting "Parsing Long Options with getopt_long"
    into Google.

    Any suggestions on what I can do?

    Kind Regards,

    Matt
     
    Matt, Jul 25, 2007
    #4
  5. Sorry, but that's not a problem with C but with a certain library
    that isn't part of the library required by the C standard. This
    newsgroup isn't too good a place to ask since there are hundreds
    of thousands of libraries written in C and you can't expect that
    all of them are discussed here. So (after reading the complete
    documentation for this library carefully) you should try to pick
    a newsgroup where it's likely to be on-topic. To my experience
    you may have more luck with this in comp.unix.programmer since
    the getopt library is often used in UNIX programs (even though
    also there it's not strictly on-topic).

    <off-topic>
    If you read the manual for the getopt library (starting at the
    beginning) you will find the following in the documentation of
    the getopt() function:

    * The default is to permute the contents of argv while scanning
    it so that eventually all the non-options are at the end[...]

    I would be rather astonished if that wouldn't also apply to the
    getopt_long() functions. I guess this would explain your obser-
    vation, making it a feature and not a bug;-)
    If you refer to lines in code you better indicate the lines clearly
    in the code itself since you never can forsee how your code will get
    mangled on the way from you to the news readers of your audience.
    At least I wasn't able to figure out which was line 124 or 135 from
    the code in your next post.
    Regards, Jens
     
    Jens Thoms Toerring, Jul 26, 2007
    #5
  6. snip 180+ lines of unreadable and uncompilable code

    Your use of // comments combined with the inevitable newsgroup line
    wrap has rendered your code uncompilable.

    You have made no effort to use consistent indenting to make your code
    readable.

    Your pretentious use of vertical white space makes your code even less
    readable.

    You define variables in the middle of blocks so those of us with C89
    compilers can't compile cleanly.

    You have been asked repeatedly to deal with these issues but can't be
    bothered.

    The output in your previous message doesn't seem to have come from
    this code. You print count before it is incremented yet somehow it
    now has a value of 2 after being initialized to 0.


    Remove del for email
     
    Barry Schwarz, Jul 26, 2007
    #6
  7. Matt

    Matt Guest

    I'll bear that in mind. Pity there isn't a specific GNU group.
    My way of getitng round it was simply to allow only one pass through
    the code. The code now executes but I am unable to pin down the non-
    arguments, which I'm not too concerned about really.
    A fair point.
     
    Matt, Jul 26, 2007
    #7
  8. At least none specific to the getopt library. In this case

    gnu.utils.help

    is the one that looks most promising to me.

    Regards, Jens
     
    Jens Thoms Toerring, Jul 26, 2007
    #8
  9. FYI, the GNU mailing lists have much higher activity than the
    newsgroups, and thus are likely to be more helpful. Google for them.
     
    Christopher Benson-Manica, Jul 26, 2007
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.