2016-10-09 5 views
-4

Новое на C, и у меня возникают проблемы с этим заданием. Я использую компилятор C89.Сортировка аргументов командной строки

Напишите программу, которая сортирует аргументы командной строки из 10 чисел, которые считаются целыми числами. Первый аргумент командной строки указывает, находится ли сортировка в порядке убывания (-d) или в порядке возрастания (-a), если пользователь вводит недопустимую опцию, программа должна отображать сообщение об ошибке.

Пример работает в программе:

./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. Используйте функцию selection_sort предназначены для проекта 5. Создайте еще одну функцию, похожий, но сорта в порядке убывания.
  2. Используйте функции библиотеки строк для обработки первого аргумента командной строки.
  3. Используйте функцию atoi для преобразования строки в целочисленную форму.
  4. Компиляция программы для создания исполняемого файла, как-то: НКУ -Wall -o рода command_sort.c

То, что я до сих пор:

#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; 
} 
+0

Рабочее задание? –

+0

Программа выглядит так, как будто она должна работать, если вы дадите ей правильные входы. –

ответ

2

Непосредственная проблема заключается в том, как ты» повторное чтение ваших аргументов.

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

Если аргументы не заданы, это будет печатать сообщение, но потом благополучно продолжать с программой и неинициализированным массивом. Он должен выйти.

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

Это также означает, что остальная часть кода не должен быть обернут в огромном else пункте. Это называется "early exit" или «ранним возвратом», что делает код намного проще.

Далее показано, как вы читаете аргументы.

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

Этот цикл предполагает наличие 10 аргументов. Если их будет меньше, он будет читать тарабарщину. Если их больше, они не будут их читать. Вместо этого используйте 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]); 
} 

В данном случае я выбрал линию i с argv и argc, потому что там больше координат. Я помещаю свое смещение в переменную, чтобы объяснить, почему она там, и не менять ее с другой.

Эта проблема с допущением, что 10 номеров являются проблемой через остальную часть кода. Вот почему я установил num_numbers, чтобы отслеживать это. Все жестко закодированные 10 можно заменить на это.

Теперь, когда 10 больше не жестко закодированы, вам нужно решить проблему, если есть больше аргументов, чем вы выделили память? Вы можете просто отвергнуть их слишком долго. Или вы можете увеличить размер вашего массива. Я оставляю вам прочитать о realloc и динамическое выделение памяти в C.


Две ноты типа.Во-первых, пока вы можете писать циклы и ifs без брекетов, всегда использовать брекеты. Зачем? Потому что в конце концов вы это напишете.

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

И вы будете смотреть на него часами, задаваясь вопросом, почему он не работает.

Следующий, // не действителен C89. Вы должны использовать /* ... */. Большинство компиляторов 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 
^ 

Это нормально, C99 позволяет // и большинство компиляторов поддерживают важные части C99 в настоящее время.

И, наконец, C с радостью позволит вам выйти из массива, пока он не сработает. Используйте средство проверки памяти, например valgrind. Это позволит вам увидеть скрытые проблемы с памятью, которые вызывают странное поведение. Так я быстро нашел вашу проблему.