tags:

views:

935

answers:

6

Hello everyone,

i want to create an object of type QApplication which needs the main functions arguments argc and argv as an input:

QApplication app(argc, argv);

Since i am within a user defined function without access to the main function i want to define this arguments on my own. I have tried several approaches but i cannot get the type conversion right. My last approach did not work either:

int argc = 1;
char **argv; 
char arguments[1][12] = {{"cgalExample"}};
argv = arguments;

Thanks for any hint.

+10  A: 

Quick and dirty, but working for QApplication:

char *argv[] = {"program name", "arg1", "arg2", NULL};
int argc = sizeof(argv) / sizeof(char*) - 1;

For a more complete and C standard conforming solution see D.Shawley's answer.

Why your solution doesn't work is simple:

array[i][j] results in a i*j matrix. But what you actually want is an array with pointers to strings in it.

Georg
Thanks a lot. This one compiles under VS 2008.
da8
Might want to mention that the first argument is the program name.
Bill
Nice correction for program name and NULL, but char* still should point to mutable strings... literal strings are not.
gimpf
Havoc is likely to be wrought if argv[argc] != NULL; code is supposed to be able to rely on that.
Jonathan Leffler
+3  A: 

Why are you concerning your self with the size of the text in argv, I would just let the compiler do it:

int argc = 1;
char* argv[] = {"Hello Qt!"}; // exactly as it is defined in main
AraK
Well, that doesn't compile for one thing: "error: brace-enclosed initializer used to initialize ‘char*’"
alex tingle
@alex It compiles fine with me (VC2008). What compiler are you using?
AraK
Yes, but isn't it required that the argv array itself is null-terminated?
gimpf
Yes, I know about `argc`, but if you spawn a process in linux, not doing so will result in a segfault; and if you search on google, there are some security notes on this.
gimpf
@gimpf argc holds the number of arguments in argv.
AraK
gcc 4.0.1: `warning: braces around scalar initializer`
Georg
@gimpf Honestly, I have no idea about programming in Linux. Isn't argc required by C/C++ standards to hold the number of arguments?
AraK
da8
@gs I tied it using VC2008 (/W4) and it doesn't give me any warning!
AraK
I did a search on this: "The array of pointers must be terminated by a NULL pointer.", see: http://linux.die.net/man/3/execYes, argc must hold the number, but it seems somebody wanted to allow for the `while(++argv)` style.
gimpf
@gimpf, this is a completely different problem. The `execl` function takes null-terminated arguments. `argv` itself isn't null-terminated.
Georg
@gs I removed the braces around the text just because I trust GCC ;)
AraK
And I'll give you back your vote. :)
Georg
@gs: the Standard requires that `argv` is `NULL` terminated. See my answer for the exact text.
D.Shawley
AraK: Here's 10p, get yourself a proper compiler :)
alex tingle
@D.Shawley: Thanks! That's really interesting.
Georg
+3  A: 

How about...

int argc = 2;
const char* argv[] ={"program","first-argument"};

...or if you need them to be non-const...

int argc = 2;
char* argv[] ={strdup("program"),strdup("first-argument")};
alex tingle
I'm agree with you. In general, first arg is the command
Patrice Bernassola
A: 

I hope this works:

char* argv[1];
argv[0] = "cgalExample";
MrMage
You are initialising char* with a const char[]. Naughty!
alex tingle
Contrary to the statement above, here it is really a problem...
gimpf
A: 

Although neither the C nor C++ standard requires it, most compilers make the arguments to main available to you as _argv and _argc. If memory serves POSIX requires this. Anyway, you need to use something like:

extern int _argc;
extern char *_argv[];

and from there you can use them about like normal.

Jerry Coffin
+9  A: 

If you want to be insanely pendantic, then you want something like the following. The key points are that argv is not const, argv is NULL terminated, argc is the number of usable elements in argv including the program name. It is required to be modifiable so you cannot use string literals - argv[i] is required to point to a modifiable array of characters.

int my_main() {
    char  arg0[] = "programName";
    char  arg1[] = "arg";
    char  arg2[] = "another arg";
    char* argv[] = { &arg0[0], &arg1[0], &arg2[0], NULL };
    int   argc   = (int)(sizeof(argv) / sizeof(argv[0])) - 1;

    QApplication the_application(argc, &argv[0]);
    return the_application.run();
}

The Standard (ISO/IEC 9899:1999 section 5.1.2.2.1) states that the following is true about argc and argv in a hosted environment:

  • 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 from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.
  • 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[0] through argv[argc-1] represent program parameters.
  • The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

QApplication states the following:

Warning: The data referred to by argc and argv must stay valid for the entire lifetime of the QApplication object. In addition, argc must be greater than zero and argv must contain at least one valid character string.

Note: argc and argv might be changed as Qt removes command line arguments that it recognizes.

D.Shawley
Thanks for this clarification!
gimpf
Just one question, should it not be (int)((sizeof ...) - 1)? Otherwise argc[argv] will point one past the NULL...
gimpf
@gimpf: just noticed that myself. Thanks.
D.Shawley
@alex tingle: take a look at clause 14 of section 6.7.8 of C99 or clause 1 of section 8.5.2 in C++98. Both clearly state that _a `char` array can be initialized from a string-literal (optionally enclosed in braces); successive characters of the string-literal initialize the members of the array._
D.Shawley
Georg
D.Shawley: You are quite right. I've retracted my comment.
alex tingle
D.Shawley
@D.Shawley: Thanks.
Georg