#include<stdio.h>
void main(int argv,char * argc[])
{
	int num1,num2;
	num1=(int)argc[1];
	num2=(int)argc[2];

	printf("%d\n",num1);
	printf("%d\n",num2);
}

wat output should i expect?
is there something wrong wid this code?
cus i am getting weird outputs

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

num1 = (int)strtol ( argv[1], NULL, 0 );
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:

if ( argc >= 3 ) {
  num1 = (int)strtol ( argv[1], NULL, 0 );
  num2 = (int)strtol ( argv[2], NULL, 0 );
  printf ( "%d\n%d\n", num1, num2 );
}

>Naure

How about using this assuming the numbers passed as strings are within the integer range...

if ( argc >= 3 ) {
num1=atoi(argv[1]);
num2=atoi(argv[2]);
printf ( "%d\n%d\n", num1, num2 );
}

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?

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

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int int_conv ( const char *src, int *result )
{
  char *end;
  long temp;
  
  errno = 0;
  temp = strtol ( src, &end, 0 );

  /* strtol failed to cleanly get a long */
  if ( !( errno == 0 && end != src && *end == '\0' ) )
    return 0;

  /* strtol succeeded, but the value is out of range */
  if ( temp < INT_MIN || temp > INT_MAX )
    return 0;

  *result = temp;

  return 1;
}

int main ( int argc, char *argv[] )
{
  int num1;
  int num2;

  if ( argc >= 3 ) {
    if ( int_conv ( argv[1], &num1 )
      && int_conv ( argv[2], &num2 ) )
    {
      printf ( "%d\n%d\n", num1, num2 );
    }
  }

  return 0;
}

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

if ( argc >= 3 
  && isdigit ( (unsigned char)argv[1] )
  && isdigit ( (unsigned char)argv[2] ) )
{
  num1 = *argv[1] - '0';
  num2 = *argv[2] - '0';
}

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[[I]negative[/I]] or lookup_table[[I]way_too_big[/I]] .

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

This article has been dead for over six months. Start a new discussion instead.