【问题标题】:Bubble sorting an array of strings in C在C中对字符串数组进行冒泡排序
【发布时间】:2020-04-27 00:55:44
【问题描述】:

我一直在尝试对字符串数组进行冒泡排序,但我总是收到“分段错误”错误。 任何帮助表示赞赏。

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

}

【问题讨论】:

  • 您的字符串是 String Literals 并且在只读内存中。 temp 也是一个未初始化的指针,它不指向任何地方。写入任何一个都可以保证 SegFault。你翻了个“蛇眼”。
  • 我明白了,谢谢!
  • 您可能想试试valgrind 工具。使用-g 编译您的程序,然后使用valgrind ./your_program 运行它。它将向您显示有关分段错误的详细信息。你会看到它发生在哪一行。

标签: c bubble-sort


【解决方案1】:

字符串文字通常存储在只读内存区域中,不打算修改。

在这个问题中,不需要移动字符串文字。相反,我们可以只修改字符串指针。它更快更安全。

请检查此代码:

    #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 *"

希望这可以帮助您解决问题。

【讨论】:

  • 唯一的问题是您不会像之前指出的那样替换 "Ruben",它仍然是字符串文字。
  • 是的,如果需要替换像“Ruben”这样的字符串文字,则需要像“strdup”这样的复制操作。但这会引入内存管理问题,需要进一步的需求细节。
【解决方案2】:

当您声明 array-of-pointers-to char 并初始化每个指向字符串的指针时,这些字符串中的每一个都是 String Literal 并且不能修改(很少有例外)。为了交换字符串,每个字符串都必须驻留在可以修改的内存中——例如数组或分配的内存块中。

在您的情况下,简单的解决方案是使 arreglo 成为二维数组而不是 指针数组,例如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

检查一下,如果您有任何问题,请告诉我。

【讨论】:

  • 非常感谢,我有一个问题,如何更改字符串的值,例如更改“Ruben”?
  • 由于它现在是可写的,您可以使用strcpy 替换"Ruben" 类似"Tom",例如排序后,"Ruben"arreglo[18],所以你可以只需执行strcpy (arreglu[18], "Tom"); 或者您可以使用memcpy 或者您可以一次更改一个字符,例如arreglo[18][0] = 'L'; 会留下"Luben"
猜你喜欢
  • 1970-01-01
  • 2018-09-22
  • 2016-12-02
  • 2017-04-14
  • 2016-02-09
  • 2014-05-08
  • 2012-11-03
  • 2015-04-17
  • 2012-04-06
相关资源
最近更新 更多