Así que soy un principiante completo en C, y estaba tratando de ordenar una serie de cadenas sin usar qsort. Aquí está el código:

#include <stdio.h>
#include <string.h>
void sort(char *ar[],int n)
{
    int i,j;
    char temp[10]; 
    for (i=0;i<n-1;i++)
    {
        for (j=0;j<n-i-1;j++)
        {
            if ((strcmp (*(ar+j),*(ar+j+1)))>0)
            {
                strcpy (temp, *(ar+j));
                strcpy (*(ar+j), *(ar+j+1));
                strcpy (*(ar+j+1), temp);
                printf ("%s\n", temp);
            }
        }
    }
    /*printf ("After sorting: \n");
    for (i=0;i<n;i++)
    printf ("%s\n", *(ar));*/
}
int main()
{
    int i,n;
    char* ar[]={"ghi","def","abc"};
    n = sizeof(ar)/sizeof(*ar);
    printf ("Before sorting: \n");
    for (i=0;i<n;i++)
    printf ("%s\n", *(ar+i));
    sort (ar,n);
    printf ("After sorting: \n");
    for (i=0;i<n;i++)
    printf ("%s\n", *(ar+i));
    return 0;
}

Sin embargo, solo imprime las cadenas antes de ordenarlas. ¿Qué estoy haciendo mal aquí?

0
nicestguy 7 may. 2020 a las 08:33

3 respuestas

La mejor respuesta

Tiene comportamiento indefinido en su función de clasificación.

Hay dos razones:

  1. Utiliza una matriz de punteros, y cada puntero apunta a una cadena literal;
  2. Utiliza strcpy para copiar contenidos entre las cadenas.

En C intentar modificar una cadena literal es comportamiento indefinido . Las cadenas literales son en esencia solo lectura . Tenga en cuenta que no son constantes, aunque siempre se recomienda utilizar punteros const.

Tienes dos formas posibles de resolver esto:

  1. Utilice una matriz de matrices en su lugar:

    char ar[][10] = { ... };
    

    Luego, el contenido de las cadenas es modificable y puede usar strcpy.

  2. O intercambia las punteras en su lugar:

    char *temp = ar[j];
    ar[j] = ar[j + 1];
    ar[j + 1] = temp;
    
3
Some programmer dude 7 may. 2020 a las 05:39

Su principal problema es que está utilizando strcpy() con literales de cadena, lo cual no está permitido. Si cambia los punteros, su algoritmo funciona perfectamente. Aquí hay una versión actualizada de sort():

void sort(char *ar[],int n)
{
    int i,j;
    char* temp; 
    for (i=0;i<n-1;i++)
    {
        for (j=0;j<n-i-1;j++)
        {
            if (strcmp (ar[j], ar[j + 1] ) > 0)  // more readable with indexing syntax
            {
                temp = ar[j];
                ar[j] = ar[j+1];
                ar[j+1] = temp;
                printf ("%s\n", temp);
            }
        }
    }
}
0
Daniel Giger 7 may. 2020 a las 05:52

Creo que es mejor usar strdup() para copiar una cadena en lugar de usar strcpy, porque la cadena anterior se almacenará en el montón mientras que la última cadena se almacenará en la pila que se pierde fácilmente después de su llamada {{ X2}}.

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

void sort(char *array[], int start, int end) {
    for (int i = start; i <= end - 1; i++) {
        for (int j = i + 1; j <= end; j++) {
            // swap if array[i] > array[j]
            if (strcmp(array[i], array[j]) > 0) {
                char *tmp = strdup(array[j]);
                array[j] = strdup(array[i]);
                array[i] = strdup(tmp);
            }
        } 
    }
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <string> ...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    sort(argv, 1, argc - 1);            // sort

    for (int i = 1; i < argc; i++) {
        printf("%s ", argv[i]);
    }
    printf("\n");

    exit(EXIT_SUCCESS);
}
$ ./sort_string_array ghi def abc

abc def ghi

O simplemente puede cambiar entre punteros en lugar de copiar una cadena a otra cadena.

0
tangyiheng 7 may. 2020 a las 06:08