Пузырьковая сортировка массива строк в C - PullRequest
1 голос
/ 27 апреля 2020

Я пытался выполнить пузырьковую сортировку массива строк, но всегда получаю сообщение об ошибке «Ошибка сегментации». Любая помощь приветствуется.

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

int main()
{
char *arreglo[20]={"Ruben","Modesta","Jan","Ana","Amparo","Josu","Azahara","Concepcio","Carmelo","Miguel","Francesc","Jairo","Jose","Luis","Teo","Jone","Jacobo","Ainoa","Natalia","Igor"};
int i;
int j;
char *temp;


for (int j=0; j<20; j++) 
{ 
    for (int i=j+1; i<20; i++) 
    { 
        if (strcmp(arreglo[j], arreglo[i]) > 0) 
        { 
            strcpy(temp, arreglo[j]); 
            strcpy(arreglo[j], arreglo[i]); 
            strcpy(arreglo[i], temp); 
        } 
    } 
} 

}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Строковые литералы обычно хранятся в области памяти, доступной только для чтения, и не предназначены для изменения.

В этом вопросе нет необходимости перемещать строковый литерал. Вместо этого мы можем просто изменить строковые указатели. Это быстрее и безопаснее.

Пожалуйста, проверьте этот код:

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

    int main()
    {
        const char *arreglo[20]={"Ruben","Modesta","Jan","Ana","Amparo","Josu","Azahara","Concepcio","Carmelo","Miguel","Francesc","Jairo","Jose","Luis","Teo","Jone","Jacobo","Ainoa","Natalia","Igor"};
        int i;
        int j;
        const char *sorted[20];

        for(i=0;i<20;i++){
            sorted[i] = arreglo[i];
        }

        for (j=0; j<20; j++){
            for (i=j+1; i<20; i++) {
                if (strcmp(sorted[j], sorted[i]) > 0) {
                    const char *temp = sorted[j];
                    sorted[j] = sorted[i];
                    sorted[i] = temp;
                }
            }
        }
        for(i=0;i<20;i++){
            printf("%d:%s\n",i,sorted[i]);
        }
    }

Указатели указатели на строковые литералы установлены на "const char *"

Надеюсь, это поможет вам решить вашу проблему.

0 голосов
/ 27 апреля 2020

Когда вы объявляете array-of-pointers-to char и инициализируете каждый указатель на строку, каждая из этих строк является String Literal и не может быть изменена ( Есть очень мало исключений). Чтобы поменять местами строки, каждая из строк должна находиться в памяти, которую можно изменить, например, в массиве или в выделенном блоке памяти.

Простое решение в вашем случае - сделать arreglo a 2D массив вместо массива указателей , например char arreglo[20][20]. Другой вариант - оставить arreglo в качестве массива указателей , но затем выделить хранилище для каждого указателя, а затем скопировать имя в каждый из выделенных блоков перед сортировкой (немного сложнее).

У вас та же проблема с temp. Вы объявляете temp как указатель, но он не инициализируется, чтобы указывать на любое допустимое хранилище, прежде чем пытаться использовать его в своей процедуре подкачки. Это также может быть просто char temp[20]; для ваших данных (хотя вам нужно только объявить их в операторе if)

Сделав эти изменения и немного изменив пределы сортировки, вы можете сделать:

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

int main (void) {

    char arreglo[20][20] = {"Ruben", "Modesta", "Jan", "Ana", "Amparo", "Josu", 
                            "Azahara", "Concepcio", "Carmelo", "Miguel", "Francesc",
                            "Jairo", "Jose", "Luis", "Teo", "Jone", "Jacobo", 
                            "Ainoa", "Natalia", "Igor"};

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

    for (int i = 0; i < 20; i++)
        puts (arreglo[i]);
}

( примечание: вам не нужно stdlib.h)

** Пример использования / вывода **

$ ./bin/bubblesort_2D_names
Ainoa
Amparo
Ana
Azahara
Carmelo
Concepcio
Francesc
Igor
Jacobo
Jairo
Jan
Jone
Jose
Josu
Luis
Miguel
Modesta
Natalia
Ruben
Teo

Просмотрите все и дайте Я знаю, если у вас есть вопросы.

...