By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 1,840 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

accessing and storing character arguements from command line

P: n/a
Hey guys

If I have a program (see codeSnippet1) that I compile to be called test.o
Then run it as test.o n n 2 3 4
I want the code to be able to strip out the two characters at the start
(always going to be 2) and store them as characters. But I can't seem to
get it to work because it is a pointer to a vector of characters.

However, if I only run with integer arguements and use codeSnippet2 it works
fine and they convert nicely to integers.

So therefore, I want to ammend my nice little loop to start converting to
integers from x=2 onwards. Which I can do fine. But how do I get the two
characters that are actual characters to be stored as characters. It
doesn't seem to be straightforward - or am I missing something stupidly
obvious?

codeSnippet1
int main(int argc, char *argv[])
{
int x;
char a, b;

/*Need these two lines to work ie get the first two arguements stored as
single characters for use elsewhere*/
a = argv[0];
b = argv[1];
/**************************/

}

codeSnippet2
int main(int argc, char *argv[])
{
int x;
int params[10];
for(x=0; x<argc; x++)
{
params[x] = atoi(argv[x]);
}
}
Nov 14 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Dawn Minnis wrote:
Hey guys

If I have a program (see codeSnippet1) that I compile to be called test.o
Then run it as test.o n n 2 3 4
I want the code to be able to strip out the two characters at the start
(always going to be 2) and store them as characters. But I can't seem to
get it to work because it is a pointer to a vector of characters.

However, if I only run with integer arguements and use codeSnippet2 it works
fine and they convert nicely to integers.

So therefore, I want to ammend my nice little loop to start converting to
integers from x=2 onwards. Which I can do fine. But how do I get the two
characters that are actual characters to be stored as characters. It
doesn't seem to be straightforward - or am I missing something stupidly
obvious?

codeSnippet1
int main(int argc, char *argv[])
{
int x;
char a, b;

/*Need these two lines to work ie get the first two arguements stored as
single characters for use elsewhere*/
a = argv[0];
b = argv[1];
/**************************/

}


a = *argv[1];
b = *argv[2];

argv is a char **, so argv[1] is a char *. If you want the char pointed
to by argv[1] you need to dereference it again... BTW, argv[0] is the
program name if such is available.

-David
Nov 14 '05 #2

P: n/a
Dawn Minnis wrote:
Hey guys

If I have a program (see codeSnippet1) that I compile to be called test.o Then run it as test.o n n 2 3 4
I want the code to be able to strip out the two characters at the start (always going to be 2) and store them as characters.
\
But how do I get the two
characters that are actual characters to be stored as characters. It doesn't seem to be straightforward - or am I missing something stupidly obvious?

You're missing the fact that main is passed a pointer to pointer to
char
(or you can think of it as an array of pointers to char).

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

The *argv[] parameter shows that main is receiving an array of pointers
to char (since arrays are really passed as pointers, this becomes a
pointer to a pointer to char - **argv is equivalent)
{
int x;
char a, b;

/*Need these two lines to work ie get the first two arguements stored as single characters for use elsewhere*/
a = argv[0];
b = argv[1];


With once subscript attached to argv, you are only dereferencing by one
level.
a is being assigned the first element in the array (which is a pointer
to the first string). b is being assigned the second element in the
array (which is a pointer to the second string). The command line
interpreter considers each word (word being a sequence of
non-whitespace characters) entered at the command line as a separate
string, where the program name is the first string (pointed to by
argv[0]).

I presume you want to work with the characters of the second string
(which is the first string after the program name). To do this, use
this type of subscripting: argv[1][i] , which is character i of string
1 (remember numbering starts at 0).

So something like this would work if the "first two characters" are NOT
separated by whitespace (which is what I assumed you wanted in the
above paragraph):

a = argv[1][0]; /* character 0 of string 1 */
b = argv[1][1]; /* character 1 of string 1 */

This would work if the first two characters are separated by
whitespace:

a = argv[1][0]; /* character 0 of string 1 */
b = argv[2][0]; /* character 0 of string 2 */

Although I wouldn't do this in a serious program because the user might
not provide the expected input at the command-line (user might enter
more than 1 character before whitespace). You are better dealing with
entire strings, which will allow you to do more error checking.
Remember, string 0 is the name of the program and is pointed to by
argv[0], so I don't think you want to play with argv[0] -pointer to
string 0- or argv[0][x] -character x of string 0-.

Nov 14 '05 #3

P: n/a
Dawn Minnis wrote:
Hey guys

If I have a program (see codeSnippet1) that I compile to be called test.o
Then run it as test.o n n 2 3 4
<OT>
It is probably not a brilliant idea to call a program *.o as often
".o" marks object files which are created by compiling a translation
unit and several of which may be linked together to obtain the final
program
</OT>
I want the code to be able to strip out the two characters at the start
(always going to be 2) and store them as characters. But I can't seem to
get it to work because it is a pointer to a vector of characters.
You do not need to "strip out" the characters. You probably mean
'n' and 'n' which are argv[1][0] and argv[2][0] in your example.
The first two characters could also be 't' and 'e' (you do not
express that clearly).
If something is a char **, you obviously have to "get rid" of
two levels of indirection, so you either want
char mycharacter, **pp = argv;
pp++; /* advance to &argv[1] */
mycharacter = **pp;
or
char mycharacter, *p = argv[1];
mycharacter = *p;
or
char mycharacter = *(argv[1]); /* gratuituous parens for clarifying */
or
char mycharacter = argv[1][0];
However, if I only run with integer arguements and use codeSnippet2 it works
fine and they convert nicely to integers.
You are converting strings to integers.
This is different from extracting one character from a string.
So therefore, I want to ammend my nice little loop to start converting to
integers from x=2 onwards. Which I can do fine. But how do I get the two
characters that are actual characters to be stored as characters. It
doesn't seem to be straightforward - or am I missing something stupidly
obvious?

codeSnippet1
int main(int argc, char *argv[])
{
int x;
char a, b;

/*Need these two lines to work ie get the first two arguements stored as
single characters for use elsewhere*/
a = argv[0];
b = argv[1];
Check for argc > 2 first. Then:
You probably want
a = *argv[1];
b = *argv[2];
argv[0] (if existing) is the name of the program. /**************************/

}

codeSnippet2
int main(int argc, char *argv[])
{
int x;
int params[10];
for(x=0; x<argc; x++)
{
params[x] = atoi(argv[x]);
This does not make sense.
Please read up on argv in your C book.
You want to have:

if (argc >= 11)
for (x=0; x<10; x++)
params[x] = atoi(argv[x+1]); }
}

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #4

P: n/a
Thank you

Lots of food for thought there.

I must have about 7 or 8 C programming books surrounding me but I still get
confused by referencing and dereferencing pointers.

Sorry about the confusion over the first element being the filename - I did
actually know that, but I wrote the code out of my head because getting the
code would have meant booting up my Linux machine and thats just too tedious
for this time of night for one bit of code.
The *argv[] parameter shows that main is receiving an array of pointers
to char (since arrays are really passed as pointers, this becomes a
pointer to a pointer to char - **argv is equivalent)


So just to clarify, even thought I have written char *argv[] it still
means a double pointer? My supervisor kept writing char **argv[] but I
thought that just overcomplicated things so I thought writing char *argv[]
lessened the level of abstraction used.

Maybe I'm away off in a world of my own again. I have a cold. Be gentle
with me.

Dawn
Nov 14 '05 #5

P: n/a
Dawn Minnis wrote:
Thank you

Lots of food for thought there.

I must have about 7 or 8 C programming books surrounding me but I still get
confused by referencing and dereferencing pointers.

Sorry about the confusion over the first element being the filename - I did
actually know that, but I wrote the code out of my head because getting the
code would have meant booting up my Linux machine and thats just too tedious
for this time of night for one bit of code.
But having three people to "repair" an error that is not there
is better?

The *argv[] parameter shows that main is receiving an array of pointers
to char (since arrays are really passed as pointers, this becomes a
pointer to a pointer to char - **argv is equivalent)


So just to clarify, even thought I have written char *argv[] it still
means a double pointer? My supervisor kept writing char **argv[] but I
thought that just overcomplicated things so I thought writing char *argv[]
lessened the level of abstraction used.


Your supervisor may have written char **argv -- certainly not
char **argv[] as this is equivalent to char ***argv in a
function parameter list.
You can think of it like that:
Arrays are never passed by value in C. Instead, the address of
the first element is passed to a function requiring a
T array[]
parameter (where T is some type). T *array also contains the
address of an object of type T -- which obviously can be the
first element of an array. The array subscripting works the
same in both cases.
Note: T array[][] does not work as a replacement for T **array.
Working out the reason is left as an exercise :-)

Maybe I'm away off in a world of my own again. I have a cold. Be gentle
with me.


Welcome to the fun world of C.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #6

P: n/a
>> Sorry about the confusion over the first element being the filename - I
did actually know that, but I wrote the code out of my head
But having three people to "repair" an error that is not there
is better?


actually, upon reflection, I didn't even notice I was doing it until it was
pointed out to me in this line:
params[x] = atoi(argv[x+1]);
Thanks for that. Now I can see that even thought I read, listened,
understood etc, I still went ahead and abandoned all rational thinking in
favour of stupid/cold-infected coding.
Your supervisor may have written char **argv -- certainly not
char **argv[] as this is equivalent to char ***argv in a
function parameter list.
Would love to concede to you on that one but afraid not. But in fairness,
he does have a tendancy to say one thing and then write another. Or
describe row-major as column-major. I think his brain is actually too
intelligent for the rest of his body to keep up.
Welcome to the fun world of C.


PAH !!! *shoots sarcastic look across the web* :-D
Nov 14 '05 #7

P: n/a
Dawn Minnis wrote:
Sorry about the confusion over the first element being the filename - I did actually know that, but I wrote the code out of my head
But having three people to "repair" an error that is not there
is better?


actually, upon reflection, I didn't even notice I was doing it until

it was pointed out to me in this line:
params[x] = atoi(argv[x+1]);
Thanks for that. Now I can see that even thought I read, listened,
understood etc, I still went ahead and abandoned all rational

thinking in favour of stupid/cold-infected coding.
Your supervisor may have written char **argv -- certainly not
char **argv[] as this is equivalent to char ***argv in a
function parameter list.
Would love to concede to you on that one but afraid not. But in

fairness, he does have a tendancy to say one thing and then write another. Or
describe row-major as column-major. I think his brain is actually too intelligent for the rest of his body to keep up.
Welcome to the fun world of C.


PAH !!! *shoots sarcastic look across the web* :-D

Long ago my opinion of this world changed from thinking it was a
meritocracy to thinking it was based mostly on other factors like
luck, timing, randmoness of the universe, politics, and a little merit
too. How your supervisor got to become a supervisor is a prime example
(especially when I know genius programmers in every country who can't
seem to find jobs).

Nov 14 '05 #8

P: n/a
Dawn Minnis wrote:
I must have about 7 or 8 C programming books surrounding me but I still get confused by referencing and dereferencing pointers.
A pointer is just an address. If you have ten cubby holes numbered 100
to 109, then at any point you will either want to know the number of
the cubby hole or you will want what is actually in it. The only tricky
part is that sometimes you have to write down and store the address of
one cubby hole in another one.
So just to clarify, even thought I have written char *argv[] it still means a double pointer?


There are only cubby hole numbers and cubby hole contents in C,
regardless of what symbols you might be using.

char** stringArray1; //an array of strings
char* stringArray2[]; //an array of strings
char stringArray3[][]; //an array of strings

In general though, I would recommend the top one for main(). What the
"imaginary" difference is between a pointer and an array is that an
array you (as the programmer) know exists and know has a set length:

char tempBuffer[100]; /*temporary buffer with a definite max length*/

While a pointer is just a way of saying, "Well I know that there's some
data over that-a-way" but you really aren't certain of the
length--probably because the length will be determined by the code
itself, not you when coding.

char* tempBuffer; /* buffer that we will allocate some random amount
of bytes to */

So when you first receive your command line arguments from main(), you
will still have no idea how many parameters the user passed in nor how
long any of those are. So as a way of pointing that out to yourself you
are better off to use two *s instead of two []s.

int main(int argc, char** argv) { /* accept any number of random
thingies from user */
return 0;
}

Note:

char* string1 = "hello"; /* set text to print out */
char string2[] = "hello"; /* generic string that we might edit later
*/

This is a case you need to be careful about. C can treat these two
cases differently, with the first one pointing to a fixed string that
might be stored in a place you aren't allowed to write to, while as the
second will always be created in a place you can fiddle about with
freely.
But if you stick to the basic idea that * just means something you
"kind of" know about, while [] is for things you are very certain about
then you should be able to remember this case. The pointer one is off
in some controlled space while as the array is over with the you and
rest of your variables.

-Chris

Nov 14 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.