![]() |
accessing and storing character arguements from command line
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]); } } |
Re: accessing and storing character arguements from command line
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 |
Re: accessing and storing character arguements from command line
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-. |
Re: accessing and storing character arguements from command line
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. |
Re: accessing and storing character arguements from command line
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 |
Re: accessing and storing character arguements from command line
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. |
Re: accessing and storing character arguements from command line
>> 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 |
Re: accessing and storing character arguements from command line
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). |
Re: accessing and storing character arguements from command line
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 |
Re: accessing and storing character arguements from command line
On 17 Feb 2005 20:58:25 -0800, "Chris Williams"
<thesagerat@yahoo.co.jp> 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 |
| All times are GMT. The time now is 12:03 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.