2015-03-26 2 views
0

Я полный новичок с C, и у нас есть назначение в классе, чтобы взять заданный список строк, поместить их в массив строк и передать это пользовательской функции сортировки, которая печатает их в алфавитном порядке. Всякий раз, когда я запускаю свой код, он не дает ошибок компилятора, но он также аварийно завершается во время выполнения. Отладка дает мне ошибку сегментации, но она не дает мне определенной строки, которая вызвала это. Я запускаю свой код через gcc-компилятор, включенный в Dev C++. Вот мой код. Любая помощь будет оценена по достоинству. Я думаю, что моя проблема заключается в том, чтобы передать массив строк в функцию, но я не смог найти ответы на эту тему, которые я мог понять.Как передать массив строк в функцию в этой программе?

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

void sort(char *[]); 

int main() 
{ 
    char *states[4] = {0}; 
    states[0] = "Florida"; 
    states[1] = "Oregon"; 
    states[2] = "California"; 
    states[3] = "Georgia"; 

    sort(states); 

    return 0; 
} 

void sort(char *ptr[]) 
{ 
    int i, j; 
    char temp[20]; 
    for (i = 1; i <= 4; i++) 
    { 
     for (j = 1; j <= 4; j++) 
      { 
       if (strcmp(ptr[j-1], ptr[j]) > 0) 
       { 
        strcpy(temp, ptr[j-1]); 
        strcpy(ptr[j-1], ptr[j]); 
        strcpy(ptr[j], temp); 
       } 
      } 
    } 

    int x; 
    for (x = 0; x < 4; x++) 
    { 
     printf("%s", ptr[x]); 
     printf("\n"); 
    } 
} 
+2

Вы сортировки указатели, а не строки. См. Также [qsort] (http://pubs.opengroup.org/onlinepubs/009695399/functions/qsort.html) –

+0

с этим 'j <= 4', тогда это' ptr [j] 'является проблемой. –

+0

'char states [] []'? – moffeltje

ответ

3

Проблема я вижу:

  1. Вы используете неправильные показатели в for петель.

    Вместо:

    for (i = 1; i <= 4; i++) 
    { 
        for (j = 1; j <= 4; j++) 
    

использование:

for (i = 0; i < 4; i++) // Keep the values in the range 0 - 3. 
    { 
     for (j = 0; j < 4; j++) 
  1. Вы изменяете память только для чтения.

    При использовании:

    states[0] = "Florida"; 
    

    states[0] имеет значение адреса только для чтения, который содержит строку "Florida". Если вы измените значения по этому адресу, который вы делаете в sort, вы вводите неопределенную территорию поведения.

Вы можете решить эту проблему, указав указатели вместо копирования значений.

// Use char* for temp instead of an array 
    char* temp; 
    if (strcmp(ptr[j-1], ptr[j]) > 0) 
    { 
     temp = ptr[j-1]; 
     ptr[j-1] = ptr[j]; 
     ptr[j] = temp; 
    } 

Добавление в ответ на комментарий OP

Следующая версия sort работает для меня:

void sort(char *ptr[]) 
{ 
    int i, j; 
    char* temp; 
    for (i = 0; i < 4; i++) 
    { 
     // NOTE: 
     // This is different from your version. 
     // This might fix your problem. 
     for (j = i+1; j < 4; j++) 
     { 
     if (strcmp(ptr[j-1], ptr[j]) > 0) 
     { 
      temp = ptr[j-1]; 
      ptr[j-1] = ptr[j]; 
      ptr[j] = temp; 
     } 
     } 
    } 

    for (i = 0; i < 4; i++) 
    { 
     printf("%s", ptr[i]); 
     printf("\n"); 
    } 
} 
+0

Ого, хорошо, что имеет большой смысл. Если вы не возражаете, чтобы я задавал другой вопрос, с этими исправлениями, я получаю вывод, но независимо от того, как я устанавливаю свой массив строк, один из них неизбежно превращается в эту длинную строку полностью случайных символов, которая является одинаковой независимо из чего имеет значение в массиве. – Llituro

+0

@Llituro, см. Обновленный ответ –

+0

Большое вам спасибо. Я не знаю, почему мой университет решил, что было бы неплохо сделать первое введение в класс программирования на C, но они это сделали. Кроме того, я действительно не знаю, почему изменение такого параметра цикла может иметь значение, но это так, поэтому еще раз спасибо. – Llituro

1

Причиной аварии является j <= 4. Другая проблема заключается в том, что вы хотите поменять указатели на строку, а не на символы.

void sort(char *ptr[]) 
{ 
    int i, j; 
    char *temp; 
    for (i = 0; i < 4; i++) // sticking to array boundary convention 
    { 
     for (j = 1; j < 4; j++) 
     { 
      if (strcmp(ptr[j-1], ptr[j]) > 0) 
      { 
       // swap pointers 
       tmp = ptr[j]; 
       ptr[j] = ptr[j-1]; 
       ptr[j-1] = ptr[j]; 
      } 
     } 
    } 

    for (i = 0; i < 4; i++) 
     printf("%s\n", ptr[i]); 
} 
0

В стандартной библиотеке C уже имеется функция для сортировки произвольных массивов данных. Он называется qsort.

qsort может сортировать массивы на основе любого критерия, который вы предоставляете, используя свой четвертый аргумент, функцию сравнения. В этом случае мы имеем естественную функцию сравнения, которую мы хотели бы использовать для использования с тем, что ожидает qsort.

Таким образом, mycmpstr ниже придает входящие указатели соответствующим образом и возвращает результат сравнения строк с использованием strcmp.Мы знаем, что qsort будет называть нашу функцию сравнения с постоянными указателями на постоянные указатели на символы, и мы «соответствующим образом» применяем.

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

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

int mycmpstr(const void *p, const void *q) { 
    const char *const *x = p; 
    const char *const *y = q; 
    return strcmp(*x, *y); 
} 

int main(void) 
{ 
    int i; 
    const char *states[] = { 
     "Florida", "Oregon", "California", "Georgia" 
    }; 

    qsort(
     states, 
     4, 
     sizeof(char *), 
     mycmpstr 
    ); 

    for (i = 0; i < 4; i += 1) { 
     puts(states[i]); 
    } 

    return 0; 
} 

Выходные:

$ clang -Wall -O1 sortex.c -o sortex 
$ ./sortex 
California 
Florida 
Georgia 
Oregon
Смежные вопросы