0

Searching the net for examples how to pass command line parameters to a C++ code, I came up with an abandoned post where this process is being explained. This code was not working and after a few amendments I came up with the following (working) code:

#include <iostream>
#include <windows.h>
#include <fstream>
#include <string>

using namespace std;

// When passing char arrays as parameters they must be pointers
int main(int argc, char* argv[]) {
    if (argc < 2) { // Check the value of argc. If not enough parameters have been passed, inform user and exit.
        std::cout << "Usage is -i <index file name including path and drive letter>\n"; // Inform the user of how to use the program
        std::cin.get();
        exit(0);
    } else { // if we got enough parameters...
        char* indFile;
        //std::cout << argv[0];
        for (int i = 1; i < argc; i++) { /* We will iterate over argv[] to get the parameters stored inside.
                                          * Note that we're starting on 1 because we don't need to know the 
                                          * path of the program, which is stored in argv[0] */
            if (i + 1 != argc) {// Check that we haven't finished parsing already
                if (strcmp(argv[i],"/x")==0) {
                    // We know the next argument *should* be the filename:
                    char indFile=*argv[i+1];
                    std::cout << "This is the value coming from std::cout << argv[i+1]: " << argv[i+1] <<"\n";
                    std::cout << "This is the value of indFile coming from char indFile=*argv[i+1]: " <<indFile  <<"\n";
                } else {
                    std::cout << argv[i]; 
                    std::cout << " Not enough or invalid arguments, please try again.\n";
                    Sleep(2000); 
                    exit(0);
                }   
            //std::cout << argv[i] << " ";
            }
        //... some more code
        std::cin.get();
        return 0;
        }   
    }
}

Executing this code from the Windows command line using:

MyProgram.exe /x filename

returns the next output:

This is the attribute of parameter /x: filename
This is the value from *argv[i+1]: f

The original post from cplusplus.com did not compile; the code above does. As you can see printing the argv[2] gives me the name of the file. When I try to capture the file name into another var so I can use it in the C++ program, I only get the first character (second response line).

Now for my question: How can I read the value from the command line parameter the pointer is pointing to? Hope someone can help this newbie in C++ :-)

J. Kruijt
  • 66
  • 1
  • 13
  • 1
    I don't get your question, you already do so in that code above? You can access the command line parameters using the `argv` array. – πάντα ῥεῖ Aug 21 '16 at 11:47
  • _"When I try to capture the file name into another var so I can use it in the C++ program ... I only get the first character "_ Assign `argv[x]` to a `std::string` not to a `char`. – πάντα ῥεῖ Aug 21 '16 at 11:48
  • Bad example! First off, that /X filename definition is problematic, becase it's technically two arguments, not one (arguments are separated by space), hence the need to access both argv[i] and argv[i+1] - normally a loop checking one arg at a time (ie argv[i] only) should be ok. Redefine the parameter as say, /Xfilename or /X=filename (filename can be enclosed in quotes if it's allowed to contain blanks too). After reading the parameters, the program must check if all required parameters were set, and while reading them it should check whether a parameter is set twice. – Constantine Georgiou Aug 21 '16 at 12:00
  • You access the command line parameters via `argv[]` variable. Your main problem is declaring `indFile` as a char. a string would work better here. Have a look at [this post](http://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean) for a better understanding of extracting – havakok Aug 21 '16 at 12:01

2 Answers2

1
*argv[i+1]

Accesses the 1st char of the char* argv[] argument.

To get the whole value use something like

std::string filename(argv[i+1]);

instead.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • This was the lead I needed to move on. I first would like to add a working piece code but after cleaning up the code it compiled correctly but when executed the programs crash. Any effort to debug didn't workout as well because debug also crashed. Anyhow, I'm happy with this part and again a tinny little smarter :-) – J. Kruijt Aug 25 '16 at 12:52
0

You can't store a string in a single char.

Here's the once-an-idiom for copying the main arguments to more manageable objects:

#include <string>
#include <vector>
using namespace std;

void foo( vector<string> const& args )
{
    // Whatever
    (void) args;
}

auto main( int n, char* raw_args[] )
    -> int
{
    vector<string> const args{ raw_args, raw_args + n };
    foo( args );
}

Do note that this code relies on an assumption that the encoding used for the main arguments can represent the actual command line arguments. That assumption holds in Unix-land, but not in Windows. In Windows, if you want to deal with non-ASCII text in command line arguments, you'd better use a third party solution or roll your own, e.g. using Windows' GetCommandLine API function.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331