【问题标题】:Bubble sort function for strings causes program crashes [closed]字符串的冒泡排序功能导致程序崩溃[关闭]
【发布时间】:2013-04-01 00:32:38
【问题描述】:

不知道怎么回事,每次在下面的代码中输入第二个字符串,都会弹出一个错误框。我正在使用 Codeblocks 作为编译器。是因为我使用指向指针的指针吗?

#include<stdio.h>
#include<conio.h>
void sort_string(char **) ;
void main()
{
    char *name[5] ;
    int x =0;
    printf("Enter Names");
    for(x = 0 ; x < 5 ; x++)
    {   fflush(stdin);
        fgets( name[x], 100,  stdin);
    }
    sort_string(name);
    for( x = 0 ; x < 5 ; x++)
    {
        puts(name[x]);

    }


}
void sort_string(char *name[5])
{
    char *temp;
    int i , j ;
    for ( i = 4 ; i >=0; i--)
    {
        for ( j = 0 ; j <=i; j ++  )
        {
            if(strcmp(name[j] > name[j+1]))
            {
                temp = name[j+1];
                name[j+1] = name[j];
                name[j] = temp;
            }
        }
    }
}

【问题讨论】:

  • fflush(stdin); 是一个未定义的操作......你在哪里分配内存来存储你正在阅读的这些字符串?
  • name[x] 是指针,需要分配内存。
  • 您能否解释一下您在此声明背后的目标strcmp(name[j] &gt; name[j+1]),因为这在语法上不正确。

标签: c string pointers bubble-sort


【解决方案1】:

正如 cmets 关于问题的所述,您需要为 name 元素分配内存。一种简单的方法是注意您将名称的长度硬编码为 99 个字符(传递给 fgets 的限制)并将您的数组更改为

char name[5][100];

一旦你这样做了,你的字符串比较就不太正确了。能改吗

if (strcmp(name[j] > name[j+1]))

if (strcmp(name[j], name[j+1]) > 0)

这将显示另一个错误。您的内部循环可以运行到j=4。然后,当您访问 name[j+1] 时,您可以读取/写入超出数组末尾的内容。这里最简单的解决方法是更改​​内部循环以更快地退出一次迭代

for (j=0 ; j<i; j++)
//          < rather than <=

【讨论】:

  • 谢谢,我的prb 被sloved..
  • 经验教训:你不能盲目地猜测 C 语法,然后通过反复试验找出类似于程序的东西。程序员必须真正知道他们代码中每一行的实际作用。
  • @simonc.. 虽然解决方案很好,但我不确定硬编码长度是否是个好主意。最初的问题是针对一组指针,我认为解决方案应该包括malloc
【解决方案2】:

fgets(名称[x], 100, 标准输入);

您正在将其复制到未分配的内存中。

char *name[5] ;

它只会创建一个大小为 5 的字符指针数组。 您必须初始化该指针的值。

【讨论】:

    【解决方案3】:

    您没有正确分配name[]。大多数现代语言都会为您分配字符串和东西,但是 C 是老派,您需要自己管理它。有几种方法可以做到这一点。

    char name[5][100];
    

    这会在堆栈上分配一个 500 字节长的本地二维数组。 name[0] 指分配开始时的 100 字符数组。 name[1][3] 指的是第二个 100 字符缓冲区中的第四个字符,它是 name 中的第 104 个字节。 name[4] 是最后一个 100 字符的数组。

    char *name[5];
    int i;
    for(i = 0; i < 5; i++) {
        name[i] = malloc(sizeof(char)*100);
    }
    

    这里,name 是一个包含 5 个char * 值的数组,大概有 40 个字节长。这些指针中的每一个都指向堆上的一个单独的 100 字节分配。您引用缓冲区和其中的字符的方式与上面的name[5][100] 相同,即使它是一个分配数组而不是二维数组。

    【讨论】:

      【解决方案4】:

      从您的代码char *name[5] 定义一个5 字符数组的数组。因此,当您执行 fgets( name[x], 100, stdin); 时,预计会为 name[x] 分配内存,因为 name[x] 是一个指针。因此,代码可以修改为

      for(x = 0; x < 5; x++)
      {
           name[x] = malloc(sizeof(char) * 100);
           fgets( name[x], 100,  stdin);
      }
      

      编辑:

      除此更改外,您还需要将simonc 建议的更改合并到strcmp 上,即条件变为if(strcmp(name[j], name[j+1]) &gt; 0),循环结构变为for ( j = 0 ; j &lt;i; j ++ )。除了上面的malloc 之外,通过这两个修改,您的代码将可以正常工作。

      【讨论】:

        猜你喜欢
        • 2013-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-13
        • 2015-11-03
        • 1970-01-01
        相关资源
        最近更新 更多