简体   繁体   中英

Sort command-line arguments

New to C and am having trouble with this work assignment. I use a C89 compiler.

Write a program that sort its command-line arguments of 10 numbers, which are assumed to be integers. The first command-line argument indicate whether the sorting is in descending order (-d) or ascending order (-a), if the user enters an invalid option, the program should display an error message.

Example runs of the program:

./sort –a 5 2 92 424 53 42 8 12 23 41
2 5 8 12 23 41 42 53 92 424

./sort –d 5 2 92 424 53 42 8 12 23 41
424 92 53 42 41 23 12 8 5 2
  1. Use the selection_sort function provided for project 5. Create another function that's similar but sorts in descending order.
  2. Use string library functions to process the first command line argument.
  3. Use atoi function in to convert a string to integer form.
  4. Compile the program to generate the executable as sort: gcc –Wall –o sort command_sort.c

What I have so far is:

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

//function prototype
void swap(int *arr, int i, int j);

//main function
int main(int argc, char *argv[])
{
     //declare the required variables
     int array[10];
     int maxIndex = 0, minIndex =0;
     int i = 0, j = 0, n = 2;

     //check whether the number of arguments are less than 2 or not
     if (argc < 2)
     {
          //print the error message
          printf("Data is insuffient! Please insert proper input at command line. \n");
     }
     else
     {   
          // read the integers from the command line
          for (i = 0; i < 10; i++)
              array[i] = atoi(argv[2 + i]);
     }

     printf("Selection sort on integer arrays \n\n");

     //print the elements that are read from the command line
     printf("Elements before sorting are: \n");

     //print the sorted elements
     for(i =0;i<10;i++)
          printf("%d ", array[i]);

     printf("\n");

     //check whether the first argument is -a, if
     //-a sort the elements in the array in asscending order
     if (strcmp(argv[1], "-a") == 0)
     {
          //logic to sort the elements in asscending order using selection sort
          for (i = 0; i < 10; ++i)
          {        
              minIndex = i;
              for (int j = i + 1; j < 10; ++j)
              {
                   if (array[j] < array[minIndex])
                        minIndex = j;
              }
              swap(array, minIndex, i);
          }
     }

     //check whether the first argument is -d, if
     //-d sort the elements in the array in descending order
     if (strcmp(argv[1], "-d") == 0)
     {   
          //logic to sort the elements in descending order using selection sort
          for (i = 0; i < 10; ++i)
          {
              maxIndex = i;
              for (j = i + 1; j < 10; ++j)
              {
                   if (array[j] > array[maxIndex])
                        maxIndex = j;
              }
              swap(array, maxIndex, i);
          }
     }

     //print the elements
     printf("\nElements after sorting are: \n");

     //print the sorted elements
     for(i =0;i<10;i++)
          printf("%d ", array[i]);

     printf("\n\n");

     return 0;
}

//definition of swap function
void swap(int *arr, int i, int j)
{
     int temp = arr[i];
     arr[i] = arr[j];
     arr[j] = temp;
}

The immediate problem is how you're reading your arguments.

 if (argc < 2)
 {
      //print the error message
      printf("Data is insuffient! Please insert proper input at command line. \n");
 }

If no arguments are given, this will print the message but then happily continue with the program and an uninitialized array. It needs to exit.

 if (argc < 2)
 {
      fprintf(stderr, "Please enter some numbers to be sorted.\n");
      exit(1);
 }

This also means the rest of the code doesn't have to be wrapped in a huge else clause. This is known as "early exit" or "early return" and it makes code much simpler.

Next is how you're reading in the arguments.

// read the integers from the command line
for (i = 0; i < 10; i++)
    array[i] = atoi(argv[2 + i]);

That loop assumes there are 10 arguments. If there are less, it will read gibberish. If there are more, it won't read them. Instead, use argc .

/* Skip the name of the program and the first option */
int argv_offset = 2;
int num_numbers = argc - argv_offset;
for( i = argv_offset; i < argc; i++ ) {
    array[i-argv_offset] = atoi(argv[i]);
}

In this case I chose to line i up with argv and argc because there's more to coordinate. I put my offset into a variable to explain why it's there and to avoid changing one with out the other.

This issue with assuming there are 10 numbers is a problem through the rest of the code. That's why I've set up num_numbers to track that. All the hard coded 10's can be replaced with that.

Now that 10 is no longer hard coded, you have to deal with the problem of what if there are more arguments than you've allocated memory for? You could just reject them as too long. Or you could grow the size of your array. I leave you to read about realloc and dynamic memory allocation in C.


Two style notes. First, while you can write loops and ifs without the braces, always use braces . Why? Because eventually you'll write this.

for( blah blah blah )
    do this thing
    and do this other thing

And you'll stare at it for hours wondering why it doesn't work.

Next, // is not valid C89. You have to use /* ... */ . Most C compilers will allow it, but if you add -std=c89 to your compiler you'll get a warning.

cc -std=c89 -Wall -g test.c -o test
test.c:5:1: warning: // comments are not allowed in this language [-Wcomment]
//function prototype
^

That's ok, C99 allows // and most compilers support the important parts of C99 now.

Finally, C will happily let you walk off an array until it crashes. Use a memory checker such as valgrind . It will let you see those hidden memory problems that cause weird behavior. This is how I found your problem so fast.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM