943,822 Members | Top Members by Rank

Ad:
  • C Discussion Thread
  • Unsolved
  • Views: 452
  • C RSS
Mar 2nd, 2009
0

command line arguements.......

Expand Post »
  1. #include<stdio.h>
  2. void main(int argv,char * argc[])
  3. {
  4. int num1,num2;
  5. num1=(int)argc[1];
  6. num2=(int)argc[2];
  7.  
  8. printf("%d\n",num1);
  9. printf("%d\n",num2);
  10. }
wat output should i expect?
is there something wrong wid this code?
cus i am getting weird outputs
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
hellIon is offline Offline
18 posts
since Nov 2008
Mar 2nd, 2009
1

Re: command line arguements.......

>is there something wrong wid this code?
Yes.

>void main(int argv,char * argc[])
main returns an int.

>num1=(int)argc[1];
>num2=(int)argc[2];
For starters, argc is the size of argv. argv is the array of strings. Next, you're expecting a cast to convert "123" to 123, which is not how things work. What a cast does is look at the same collection of bytes in a different way. Try strtol for an actual conversion from a string type to an integer type:
  1. num1 = (int)strtol ( argv[1], NULL, 0 );
  2. num2 = (int)strtol ( argv[2], NULL, 0 );
Finally, you should be checking the value of argc to make sure that there really are enough elements in argv to index up to 2:
  1. if ( argc >= 3 ) {
  2. num1 = (int)strtol ( argv[1], NULL, 0 );
  3. num2 = (int)strtol ( argv[2], NULL, 0 );
  4. printf ( "%d\n%d\n", num1, num2 );
  5. }
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
Mar 2nd, 2009
0

Re: command line arguements.......

>Naure

How about using this assuming the numbers passed as strings are within the integer range...
  1. if ( argc >= 3 ) {
  2. num1=atoi(argv[1]);
  3. num2=atoi(argv[2]);
  4. printf ( "%d\n%d\n", num1, num2 );
  5. }

Or if the coder is sure to get only singe digit numbers he/she can just use "Number" - 48 which would be faster than any of the above mentioned functions right?
Reputation Points: 485
Solved Threads: 88
Posting Pro
csurfer is offline Offline
564 posts
since Jan 2009
Mar 2nd, 2009
1

Re: command line arguements.......

>How about using this assuming the numbers passed as strings are within the integer range...
If your assumption holds, that's fine. But that's a pretty big assumption when it comes to user input. atoi is notoriously bad at handling errors, so it would be wise to forget that family of functions even exists.

Of course, my example isn't much better as it uses the lazy method of converting with strtol. There are a number of things that could go wrong which make that method weak in terms of robustness. But the fix is pretty verbose in comparison:
  1. #include <errno.h>
  2. #include <limits.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5.  
  6. int int_conv ( const char *src, int *result )
  7. {
  8. char *end;
  9. long temp;
  10.  
  11. errno = 0;
  12. temp = strtol ( src, &end, 0 );
  13.  
  14. /* strtol failed to cleanly get a long */
  15. if ( !( errno == 0 && end != src && *end == '\0' ) )
  16. return 0;
  17.  
  18. /* strtol succeeded, but the value is out of range */
  19. if ( temp < INT_MIN || temp > INT_MAX )
  20. return 0;
  21.  
  22. *result = temp;
  23.  
  24. return 1;
  25. }
  26.  
  27. int main ( int argc, char *argv[] )
  28. {
  29. int num1;
  30. int num2;
  31.  
  32. if ( argc >= 3 ) {
  33. if ( int_conv ( argv[1], &num1 )
  34. && int_conv ( argv[2], &num2 ) )
  35. {
  36. printf ( "%d\n%d\n", num1, num2 );
  37. }
  38. }
  39.  
  40. return 0;
  41. }
>Or if the coder is sure to get only singe digit numbers he/she can
>just use "Number" - 48 which would be faster than any of the
>above mentioned functions right?
Yes, though one shouldn't use a magic number when an abstract alternative exists. If you only need the first digit from the arguments, you can do this:
  1. if ( argc >= 3
  2. && isdigit ( (unsigned char)argv[1] )
  3. && isdigit ( (unsigned char)argv[2] ) )
  4. {
  5. num1 = *argv[1] - '0';
  6. num2 = *argv[2] - '0';
  7. }
Using '0' means your code will continue to work even with character sets where '0' doesn't have a value of 48 (EBCDIC is one such character set).

Since you're interested in the nooks and crannies, I'll also explain why I used a cast in the call to isdigit. While isdigit accepts an integer argument, that integer must be either EOF or in the range of unsigned char. This is a hard rule because the typical implementation of the is* and to* functions is a lookup table. If the value is out of the range of unsigned char, you're looking at an out of bounds array access.

argv is an "array" of pointers to char, but it's implementation defined whether the vanilla char type is signed or unsigned. It's also implementation defined what values are contained in argv, which includes the range of characters. If the value is outside of the expected range without first forcing it into the correct range, the promotion to int won't fix anything, and you invoke undefined behavior by essentially saying lookup_table[negative] or lookup_table[way_too_big] .

This isn't an issue with input functions like getchar because they're guaranteed to give you the correct values (either EOF or an unsigned char range).
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C Forum Timeline: how to write numbers in reverse order
Next Thread in C Forum Timeline: Array to an output file





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC