how to write a program that takes arguments from commandline?

  • Thread starter =?ISO-8859-1?Q?Martin_J=F8rgensen?=
  • Start date
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Hi,

I'm learning C-programming. I have a program which I would like to
modify so it takes arguments from the commandline. Let call the program:
program.exe.

Could somebody shortly explain how I get this behaviour:

C:>program -help or C:>program -h
printf("\nBla. bla. Here is some help and arguments\n").... etc.

C:>program -dt=0.1 -tend=10 (etc. additional switches might be added).
In the program:

float (or double) dt should become 0.1. The integer variable named
"tend" should be assigned respectively to 10.

In case of any problems such as for instance C:>program dt=adg, the
program should respond with something like "dt: Invalid syntax. Exiting.".

I suspect that one should change the program such that "int main(??
something goes in here, right?)" instead of int main(void), but I'm not
really sure of how to address this problem. If somebody has any sample
code in C to post, I would be very happy.

Thanks in advance for any hints...


Med venlig hilsen / Best regards
Martin Jørgensen
 
W

Walter Roberson

I'm learning C-programming. I have a program which I would like to
modify so it takes arguments from the commandline.
I suspect that one should change the program such that "int main(??
something goes in here, right?)" instead of int main(void), but I'm not
really sure of how to address this problem.

Ummm, I cannot think of any introductory C text which does not
cover the mechanics of passing in arguments.

The harder part is in cleanly and efficiently parsing what gets passed in,
especially if some options modify the meaning of others or some
options cannot co-exist with others. For the mechanics, see most
any program and look for argc and argv .
 
A

Alvin

You're right, when you define main, you do:
int main(int argc, char *argv[])
argc is the number of arguments specified, program.exe would count as
an argument, too.
argv is the arguments given. It's a constant array, so it starts at [0]
(that would be program.exe). [1] would be -h or -help, and so on. I've
seen argv written as char **argv rather than the conventional char
*argv[], but I guess it's down to you.

One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
 
S

stathis gotsis

Martin Jørgensen said:
Hi,

I'm learning C-programming. I have a program which I would like to
modify so it takes arguments from the commandline. Let call the program:
program.exe.

Could somebody shortly explain how I get this behaviour:

C:>program -help or C:>program -h
printf("\nBla. bla. Here is some help and arguments\n").... etc.

C:>program -dt=0.1 -tend=10 (etc. additional switches might be added).
In the program:

float (or double) dt should become 0.1. The integer variable named
"tend" should be assigned respectively to 10.

In case of any problems such as for instance C:>program dt=adg, the
program should respond with something like "dt: Invalid syntax. Exiting.".

I suspect that one should change the program such that "int main(??
something goes in here, right?)" instead of int main(void), but I'm not
really sure of how to address this problem. If somebody has any sample
code in C to post, I would be very happy.

Thanks in advance for any hints...

Maybe this is relevant:
http://c-faq.com/misc/argv.html
 
J

Joe Wright

Alvin wrote:
[ much snippage ]
One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
---
if(argv[1] == "-help")
printf("\n<help>");
else
printf("\nyou typed %s", argv[1]);
Wrong completely. 'if (argv[1] == "-help")' can never be expected to
'work' in your wildest dreams. argv[1] is a char* supplied by the
command processor, "-help" is a char* to an anonymous array of char
somewhere in memory. They will not ever be equal. Never.

strcmp() is your friend.
 
B

boa

Joe said:
Alvin wrote:
[ much snippage ]
One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
---
if(argv[1] == "-help")
printf("\n<help>");
else
printf("\nyou typed %s", argv[1]);
-------^^^^^^^^^^^^^^^^
Did you miss this part?
Wrong completely. 'if (argv[1] == "-help")' can never be expected to
'work' in your wildest dreams. argv[1] is a char* supplied by the
command processor, "-help" is a char* to an anonymous array of char
somewhere in memory. They will not ever be equal. Never.

strcmp() is your friend.


boa
 
J

Joe Wright

boa said:
Joe said:
Alvin wrote:
[ much snippage ]
One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
---
if(argv[1] == "-help")
printf("\n<help>");
else
printf("\nyou typed %s", argv[1]);

-------^^^^^^^^^^^^^^^^
Did you miss this part?
I don't think so. What might I have missed? Sarcasm? Maybe.
Wrong completely. 'if (argv[1] == "-help")' can never be expected to
'work' in your wildest dreams. argv[1] is a char* supplied by the
command processor, "-help" is a char* to an anonymous array of char
somewhere in memory. They will not ever be equal. Never.

strcmp() is your friend.


boa
 
A

Alvin

*hits forhead*
Should have thought of using that before!
Thanks very much, Joe! I was worried I was going to get a stingy reply
with no help at all.
 
K

Keith Thompson

Alvin said:
*hits forhead*
Should have thought of using that before!
Thanks very much, Joe! I was worried I was going to get a stingy reply
with no help at all.

Should have thought of using what before?

Don't assume we can easily see the article to which you're replying.
Please read <http://cfaj.freeshell.org/google/>.
 
B

boa

Joe said:
boa said:
Joe said:
Alvin wrote:
[ much snippage ]


One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
---
if(argv[1] == "-help")
printf("\n<help>");
else
printf("\nyou typed %s", argv[1]);

-------^^^^^^^^^^^^^^^^
Did you miss this part?
I don't think so. What might I have missed? Sarcasm? Maybe.


My mistake. I messed up and for some reason thought that you responded
to someone other than the OP, and thought that you didn't "get" the
(rather poor) example of why one cannot compare string values like that
in C.

Sorry about that.
boa
[snip]
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

stathis gotsis wrote:
-snip-

Thanks. That looks exactly like the place to start. Also thanks to the
other answers. I assume argc contains the number of (space-separated)
arguments.


Med venlig hilsen / Best regards
Martin Jørgensen
 
K

Keith Thompson

Martin Jørgensen said:
stathis gotsis wrote:
-snip-


Thanks. That looks exactly like the place to start. Also thanks to the
other answers. I assume argc contains the number of (space-separated)
arguments.

The arguments aren't necessarily space-separated; that depends on the
mechanism (for example, a shell) used to invoke your program.

argc is the number of valid elements of the array pointed to by argv.
If you invoke your program with 2 command-line arguments, argc will be 3.
argv[0] probably points to (some form of) the name of your program;
argv[1] and argv[2] point to your command-line arguments.
 
M

Mark McIntyre

One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work.

you can't compare strings like that. This is why strcmp and its
friends exist.,
Mark McIntyre
 
M

Mark McIntyre

Joe said:
Alvin wrote:
[ much snippage ]
One problem I've run into is this: when testing for an argument, say:
if(argv[1] == "-help")
in your case, it doesn't work. If you try:
---
if(argv[1] == "-help")
printf("\n<help>");
else
printf("\nyou typed %s", argv[1]);
-------^^^^^^^^^^^^^^^^
Did you miss this part?

No, he didn't. Its meaningless to compare strings using ==, unless
both are the same object it will almost inevitably fail (all you're
doing is comparing the pointers). So naturally it drops down to the
else.
Mark McIntyre
 
P

pete

Martin Jørgensen wrote:
I suspect that one should change the program such that "int main(??
something goes in here, right?)" instead of int main(void),
but I'm not
really sure of how to address this problem. If somebody has any sample
code in C to post, I would be very happy.

/* BEGIN type_.c */
/*
** This is a demonstration of a way to use fscanf
** to read lines from text files.
*/
#include <stdio.h>

#define ARGV_0 type_
#define LINE_LEN 250
#define str(s) # s
#define xstr(s) str(s)

int main(int argc, char *argv[])
{
int rc;
FILE *fd;
char line[LINE_LEN + 1];

if (argc > 1) {
while (*++argv != NULL) {
fd = fopen(*argv, "r");
if (fd != NULL) {
do {
rc = fscanf(fd,
"%" xstr(LINE_LEN) "[^\n]%*[^\n]", line);
if (!feof(fd)) {
getc(fd);
}
if (rc == 0) {
*line = '\0';
}
if (rc != EOF) {
puts(line);
}
} while (rc == 1 || rc == 0);
fclose(fd);
} else {
fprintf(stderr,
"\nfopen() problem with \"%s\"\n", *argv);
break;
}
}
} else {
puts(
"Usage:\n>" xstr(ARGV_0)
" <FILE_0.txt> <FILE_1.txt> <FILE_2.txt> ...\n"
);
}
return 0;
}

/* END type_.c */
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Keith said:
The arguments aren't necessarily space-separated; that depends on the
mechanism (for example, a shell) used to invoke your program.

If the arguments isn't space-separated, how else would they be separated?
argc is the number of valid elements of the array pointed to by argv.
If you invoke your program with 2 command-line arguments, argc will be 3.
argv[0] probably points to (some form of) the name of your program;
argv[1] and argv[2] point to your command-line arguments.

Just as I thought.


Med venlig hilsen / Best regards
Martin Jørgensen
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

pete wrote:
-snip-
/* END type_.c */

Thanks for the example. Looks a little advanced but I'll try it out...


Med venlig hilsen / Best regards
Martin Jørgensen
 
W

William J. Leary Jr.

Martin Jørgensen said:
If the arguments isn't space-separated, how else would they be separated?

I've encountered two variations:

program argument1,argument2,argument with space,,argument 5

program/argument1/argument2/argument with space//argument 5

These both got argc == 6 with

argv[0] = "" (neither of them gave the program name in any form)
argv[1] = "argument1"
argv[2] = "argument2"
argv[3] = "argument with space"
argv[4] = ""
argv[5] = "argument 5"

The touted advantage of both was that you could have spaces, or even empties,
in the list. One of them discarded leading and trailing blanks. The other
didn't. I don't recall which now, but for the one that didn't, committing the
typo of

program argument1, argument 2

got you

argv[1] = "argument1"
argv[2] = " argument 2"

I was targeting both of these at the same time, so I just coded to remove
leading and trailing blanks no matter what.

- Bill
 
P

pete

Martin said:
pete wrote:
-snip-

Thanks for the example. Looks a little advanced but I'll try it out...

The command line agurment part
isn't especially advanced, I don't think.

The fprintf part *is* a little bit advanced.
 
P

pete

pete said:
The command line agurment part
isn't especially advanced, I don't think.

But I should explain it anyway.

For this form of main: int main(int argc, char *argv[]);

argc is the number of command line arguments.
argv is the NULL terminated array of pointers to strings,
where the strings are command line arguments.
The name of the program is the first argument.

A system need not support command line arguments at all,
in which case arc may be equal to zero,
this something that should be checked for.
If command line arguments are supported,
then the first one will be the name of the program.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top