简体   繁体   English

排序命令行参数

[英]Sort command-line arguments

New to C and am having trouble with this work assignment. C 语言新手,在完成这项工作任务时遇到了问题。 I use a C89 compiler.我使用 C89 编译器。

Write a program that sort its command-line arguments of 10 numbers, which are assumed to be integers.编写一个程序,对它的 10 个数字的命令行参数进行排序,假设这些数字是整数。 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.第一个命令行参数指示排序是按降序 (-d) 还是升序 (-a),如果用户输入无效选项,程序应显示错误消息。

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.使用为项目 5 提供的 selection_sort 函数。创建另一个类似但按降序排序的函数。
  2. Use string library functions to process the first command line argument.使用字符串库函数处理第一个命令行参数。
  3. Use atoi function in to convert a string to integer form.使用 atoi 函数将字符串转换为整数形式。
  4. Compile the program to generate the executable as sort: gcc –Wall –o sort command_sort.c编译程序以将可执行文件生成为 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.这也意味着其余的代码不必包含在一个巨大的else子句中。 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.该循环假设有 10 个参数。 If there are less, it will read gibberish.如果少,它会读到胡言乱语。 If there are more, it won't read them.如果有更多,它不会读取它们。 Instead, use argc .相反,使用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.在这种情况下,我选择将iargvargc因为还有更多需要协调。 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.假设有 10 个数字的这个问题是代码其余部分的问题。 That's why I've set up num_numbers to track that.这就是我设置num_numbers来跟踪它的原因。 All the hard coded 10's can be replaced with that.所有硬编码的 10 都可以用它替换。

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?现在 10 不再是硬编码的,您必须处理以下问题:如果参数比您分配的内存多怎么办? 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.我让您阅读有关 C 中的realloc和动态内存分配的信息。


Two style notes.两个风格笔记。 First, while you can write loops and ifs without the braces, always use braces .首先,虽然您可以在没有大括号的情况下编写循环和 ifs,但始终使用大括号 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.接下来, //不是有效的 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.大多数 C 编译器都会允许它,但是如果您将-std=c89添加到您的编译器中,您将收到警告。

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.没关系,C99 允许//现在大多数编译器都支持 C99 的重要部分。

Finally, C will happily let you walk off an array until it crashes.最后,C 会很高兴地让你离开一个数组,直到它崩溃。 Use a memory checker such as valgrind .使用内存检查器,例如valgrind It will let you see those hidden memory problems that cause weird behavior.它会让你看到那些导致奇怪行为的隐藏内存问题。 This is how I found your problem so fast.这就是我如何如此快速地发现您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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