0

I am writing a program that finds if either -l for find largest or -s for find smallest appears when the user inputs the string into the command line. For example ./a.out -l 2 4 6 would find the largest of the users input. In my program I am unsure if I should use atoi or if I can get by without. Also am I able to use the a pointer for the first part of my program and user the actual array in the second half to find the smallest or largest number? Since the ./a.out and -l is stored in array[0] and array [1] can I skip those and still find the largest and smallest numbers? I have written the code to find the largest and smallest number in an array but I am unsure if it is compatible. Any help would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

  int x,i;

  for(; *argv != '\0'; argv++){ //checks to see if -l is in string
    if (strcmp(*argv,"-l") == 0){
      x = 1;  //easier to use x value than nested fors and ifs
      break;
  }
    if(strcmp(*argv,"-s") == 0){ //checks if -s is in string
      x = 2;
      break; 
  } 
    else{  //if neither 
     printf("Error invalid option");
     break;
  }
}

  if(x == 1){ //is going to find the largest element
   for(i=2;i<argc;++i){
       if(argv[2]<argv[i]) 
           argv[2]=argv[i];
  }
   printf("Largest element is %d", argv[2]); 
}

  if( x == 2){ //find smallest element 
    for(i=2;i<argc;++i){
           if(argv[2]>argv[i]) 
               argv[2]=argv[i];
  }
    printf("Smallest element is %d", argv[2]); 
}
  return 0;
}
cs95
  • 379,657
  • 97
  • 704
  • 746
  • Why don't you turn the warnings on your compiler on? BTW, what does your question have to do with pointers? – user3078414 Jul 02 '16 at 21:13
  • In `if(argv[2]>argv[i]) argv[2]=argv[i];` firstly that is not the way to compare strings, let alone numbers. Secondly, it's not a good idea to try swapping around the arguments provided. Your suggestion of `atoi` is good, but I would use `sscanf` to more easily check whether there really is a valid argument of the type you are expecting. – Weather Vane Jul 02 '16 at 21:15

2 Answers2

1

This is not a good idea.

char **argv is a pointer to an array of strings.

When you run your program with command line arguments, argc is initialised to the number of arguments passed, while argv will point to an array of string pointers pointing to the strings, somewhat like this:

A representation of argv

The first argument is always the name of your executable, and the last element of argv is always grounded (set to NULL). For more information, see here.

Using arithmetic operations on the elements of argv will actually carry out arithmetic on the pointers pointing to those strings, leading to behaviour you most likely don't want.

You must either fall back on using atoi() or write your own function to do so.

Community
  • 1
  • 1
cs95
  • 379,657
  • 97
  • 704
  • 746
0

Your set of arguments is:

argv[0] "program_name"
argv[1] "-l" (or "-s")  [program options]
argv[2] "<first_number>"
… 
argv[argc-1] "<last_number>"
NULL

They are all read by the program as "C-strings", which are '\0' terminated character arrays in fact. So, char *argv[] is an a pointer to an array of character arrays. For more information please see this SO post and this SO post. There is no point in running a for loop (which is erratic in your case, btw) in order to detect which argument is the program option if you know it is the first, and the rest of your code shows you know.
If you are sure that the arguments to follow are numbers and you want to compare their arithmetic values, you first have to interpret them as numbers. atoi() is the function which returns the converted integral number string as int value. You also need the result values initialized to minimal or maximal value for the given data type. I don't see much use of incrementing pointers (*++argv) and a while loop in counting through arguments of main(). Using array subscriptions and a for loop are much easier to read. Here is a quick, though not entirely fool-proof fix of your code:

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

int main(int argc, char *argv[])
{
  int x,i,m,n = 0;
  if (strcmp(argv[1],"-l") == 0)
      x = 1;
  else if (strcmp(argv[1],"-s") == 0)
      x = 2;
  else{
     printf("Error: invalid option");
     return(1);
  }

  if(x == 1){ //is going to find the largest element
  m = INT_MIN;  
  for(i=2;i<argc;++i){
      if(atoi(argv[i]) >= m){
          m = atoi(argv[i]);
          n = i;
      }
    }
    printf("Largest is the element #%d, equaling %d\n", n-1, m); 
  }

  if( x == 2){ //find smallest element 
    m = INT_MAX;
    for(i=2;i<argc;++i){
      if(atoi(argv[i]) <= m){
          m = atoi(argv[i]);
          n = i;
      }          
    }
    printf("Smallest is the element #%d, equaling %d\n", n-1, m); 
  }
  return 0;
}
Community
  • 1
  • 1
user3078414
  • 1,942
  • 2
  • 16
  • 24