简体   繁体   English

使用没有 qsort 的指针对 C 中的字符串数组进行排序

[英]Sorting an array of strings in C using pointers without qsort

So I am a complete beginner to C, and I was trying to sort an array of strings without using qsort.所以我是 C 的完整初学者,我试图在不使用 qsort 的情况下对字符串数组进行排序。 Here is the code:这是代码:

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

However, it only prints the strings before sorting.但是,它只在排序之前打印字符串。 What am I doing wrong here?我在这里做错了什么?

You have undefined behavior in your sorting function.您在排序 function 中有未定义的行为

There are two reasons:有两个原因:

  1. You use an array of pointers, and each pointer is pointing to a literal string;您使用一个指针数组,每个指针都指向一个文字字符串;
  2. You use strcpy to copy contents between the strings.您使用strcpy在字符串之间复制内容。

In C attempting to modify a literal string is undefined behavior .在 C 中,试图修改文字字符串是未定义的行为 Literal strings are in essence read-only .文字字符串本质上是只读的 Note that they are not constant, even through it's always recommended to use const pointers.请注意,它们不是常量,即使始终建议使用const指针。

You have two possible way of solving this:你有两种可能的方法来解决这个问题:

  1. Use an array of arrays instead:请改用 arrays 数组:

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

    Then the contents of the strings are modifiable, and you can use strcpy .然后字符串的内容是可修改的,你可以使用strcpy

  2. Or swap the pointers instead:或者交换指针:

     char *temp = ar[j]; ar[j] = ar[j + 1]; ar[j + 1] = temp;

Your main problem is that you're using strcpy() with string literals, which isn't allowed.您的主要问题是您将strcpy()与字符串文字一起使用,这是不允许的。 If you swap the pointers instead, your algorithm works perfectly.如果您交换指针,您的算法将完美运行。 Here's an updated version of sort() :这是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);
            }
        }
    }
}

I think you'd better use strdup() to copy a string instead of using strcpy , because the former string will store in heap while the latter string will store in stack which is easily lost after your calling sort() .我认为您最好使用strdup()来复制字符串而不是使用strcpy ,因为前一个字符串将存储在堆中,而后一个字符串将存储在堆栈中,这在您调用sort()后很容易丢失。

#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

or you could just swap between pointers instead of copying one string to another string.或者您可以只在指针之间交换,而不是将一个字符串复制到另一个字符串。

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

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