Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > accessing and storing character arguements from command line

Reply
Thread Tools

accessing and storing character arguements from command line

 
 
Dawn Minnis
Guest
Posts: n/a
 
      02-17-2005
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]);
}
}


 
Reply With Quote
 
 
 
 
David Resnick
Guest
Posts: n/a
 
      02-17-2005
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
 
Reply With Quote
 
 
 
 
Kiru Sengal
Guest
Posts: n/a
 
      02-17-2005
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-.

 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      02-17-2005
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.
 
Reply With Quote
 
Dawn Minnis
Guest
Posts: n/a
 
      02-17-2005
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


 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      02-17-2005
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.
 
Reply With Quote
 
Dawn Minnis
Guest
Posts: n/a
 
      02-17-2005
>> 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*


 
Reply With Quote
 
Kenneth Bull
Guest
Posts: n/a
 
      02-17-2005
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*



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).

 
Reply With Quote
 
Chris Williams
Guest
Posts: n/a
 
      02-18-2005
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

 
Reply With Quote
 
Dave Thompson
Guest
Posts: n/a
 
      02-28-2005
On 17 Feb 2005 20:58:25 -0800, "Chris Williams"
<(E-Mail Removed)> wrote:

> 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?

>

Yes.

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

Sort of. With the caveat that different cubbyholes have different
'shapes' -- and thus certain cubbyhole numbers can only be used to
point to (and store or fetch) certain kinds of contents.

> 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:
>

No. Arrays in C are really arrays not just pre-set pointers as they
were in B and BCPL; in all but a few cases they _convert_ to a
pointer, which we informally call decay. The first two are equivalent
_for a function parameter_ because a parameter whose type is array is
'rewritten' as a pointer -- at the top level only; they are not
equivalent for a variable. The third is not the same ever, and is
outright illegal in C99 -- you now cannot even declare an array of
incomplete type. See FAQ section 6 at the usual places and
http://www.eskimo.com/~scs/C-faq/top.html .

> 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.
>

Length not known in advance is one reason; "I want to control the
lifetime" (less than static but more than automatic) is another and "I
want to access different things in different circumstances" a third.

Aside: I would say the length is determined by the code at execution
time, or by execution of the code; even a staticly declared length is
still 'determined by the code'.

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

Not truly random, except in very rare cases, but variable and perhaps
even random-seeming. <G>

> 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;
> }
>

Arguable. Either char** or char*[] is the same to the compiler in this
context. Some people prefer to see that it is really a pointer (which
is used to access an array); some people prefer to see that its
'purpose' is to access the array. Six of one ....

> 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.


Right. More precisely, it violates the standard to write into the
first (literal) string no matter how the compiler stores it. It is
legal to modify the second -- but only within its allocated length,
which for the example given means you can't _extend_ it.

> 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


- David.Thompson1 at worldnet.att.net
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
perl command line arguements mrinalini.sukumar@gmail.com Perl Misc 1 11-10-2006 02:45 AM
command line arguements with spaces in them raphfrk@netscape.net C Programming 40 07-24-2006 11:14 PM
ReadOnly Properties - Arguements For/Against Rob Meade ASP .Net 5 12-05-2005 03:53 PM
Error Installing Eng-US Language Packs, 208 Invalid Arguements, Firefox 1.0.2 pixturesk@hotmail.com Firefox 6 03-26-2005 01:50 AM
sending command line arguements to HTML Tidy d davis Perl 0 04-27-2004 02:23 PM



Advertisments