0

我正在为我的 CECS 课程分配电话簿,但在按字母顺序排序联系人时遇到了问题。该程序最多允许我对 3 个联系人进行排序,但是当我尝试对 3 个以上的联系人进行排序时,程序开始吐出垃圾变量并可能崩溃。

void Sort(phone *phonebook, int *num_entries)
{
 int tracker = *num_entries;
 if (tracker >= 0)
 {
 phone *temp = (phone*) calloc(tracker, sizeof(phone));
 if (temp== NULL)
    printf("\n\nOut of memory\n\n");
 else
 {
 int i, j;
 for (i = 0; i < tracker; i++)
 {
     for (j = i+1; j < tracker; j++)
     {
         //Combines first and last names into 1 name for easy comparison
         strcpy(phonebook[i].totalname, phonebook[i].fName);
         strcpy(phonebook[j].totalname, phonebook[j].fName);
         strcat(phonebook[i].totalname, phonebook[i].lName);
         strcat(phonebook[j].totalname, phonebook[j].lName);
         printf("\nTotal name = %s\nTotal name = %s", phonebook[i].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
         if (strcmp(phonebook[i].totalname, phonebook[j].totalname) > 0)
         {
            strcpy(temp[i].fName, phonebook[i].fName);
            strcpy(temp[i].lName, phonebook[i].lName);
            temp[i].number = phonebook[i].number;
            temp[i].area = phonebook[i].area;

            strcpy(phonebook[i].fName, phonebook[j].fName);
            strcpy(phonebook[i].lName, phonebook[j].lName);
            phonebook[i].number = phonebook[j].number;
            phonebook[i].area = phonebook[j].area;

            strcpy(phonebook[j].fName, temp[i].fName);
            strcpy(phonebook[j].lName, temp[i].lName);
            phonebook[j].number = temp[i].number;
            phonebook[j].area = temp[i].area;
         }
     }
 }
 printf("\n\nSuccessfully sorted!\n\n");
 }
 }
 else
 printf("\n\nYou need people in the phone book before you can sort it.\n\n");
 }

 -------------------------
 typedef struct PhoneBook
 {
   char fName[20];
   char lName[20];
   char totalname[40];
   float number;
   int area;    
  } phone;

编辑以添加结构。而且我不使用 qsort,因为我们在课堂上还没有学到它,而且 TA 对不使用我们没有学过的东西相当严格。

void Add(phone *phonebook, int *num_entries)
{    
 int tracker = *num_entries;
 if (tracker == 0)
 {
    printf("\n\nSomething's wrong here\n\n");
 }
 else
 {
      const int newSize = tracker + 1;
      phone *temp = (phone*) realloc(phonebook, (newSize * sizeof(phone)));
      if (temp!=NULL)
      {
         phonebook = temp;
      }
      else
          phonebook = NULL;
 }
 if (phonebook == NULL)
    printf("\n\nOut of memory, can't add more to your phonebook\n\n");
 else
 {
     printf("\n\nEnter the first name: ");
     scanf("%s", phonebook[tracker].fName);
     printf("\nPlease enter the last name: ");
     scanf("%s", phonebook[tracker].lName);
     printf("\nPlease enter the area code: ");
     scanf("%d", &phonebook[tracker].area);
     printf("\nPlease enter the phone number (no dashes allowed): ");
     scanf("%f", &phonebook[tracker].number);
     *num_entries += 1;
     printf("\nContact Added.\n\n");
 }
}

再次编辑以显示将人员添加到电话簿的代码(也已损坏)。在 3-4 个条目之后,它开始为条目放置垃圾值。

int main()
{
int userInput = 8; //means exit
int num_entries = 1;
phone *phonebook = (phone*) calloc(1 , sizeof(phone));
if (phonebook == NULL)
    printf("\n\nOut of memory\n\n");
else
{
do
{
     system("cls"); 
     printf("Menu: \n");
     printf("1) Add a Contact\n");
     printf("2) Delete a Contact\n");
     printf("3) Display Phone Book\n");
     printf("4) Alphabetically Sort\n");
     printf("5) Find a Contact\n");
     printf("6) Random Contact\n");
     printf("7) Delete All\n");
     printf("8) Exit\n\n");
     scanf(" %d", &userInput);

     switch (userInput)
     {
            case 1: //Add a Friend
                 Add(phonebook, &num_entries);
                 break;
            case 2: //Delete a Friend
                 Delete(phonebook, &num_entries);
                 break;
            case 3: //List all contacts
                 Display(phonebook, &num_entries);
                 break;
            case 4:
                 Sort(phonebook, &num_entries);
                 break;
            case 5:
                 Find(phonebook, &num_entries);
                 break;
            case 6:
                 Random(phonebook, &num_entries);
                 break;
            case 7:
                 DeleteAll(phonebook, &num_entries);
                 break;
            case 8:
                 free(phonebook);
                 break;
     }
     system("PAUSE");  
  }while(userInput != 8);
 }
 return 0;
}

编辑显示每个函数的调用

好吧,我不能在没有更多声誉的情况下发布照片,所以这里是链接:照片 1 - 添加 3 个联系人可以正常工作:http://s980.photobucket.com/user/valondon/media/C%20Realloc%20Errors/Erroronerealloc_zpsc8228131.png。 html?sort=3&o=0 图2 - 添加第四个联系人后的电话簿:http ://s980.photobucket.com/user/valondon/media/C%20Realloc%20Errors/Errorthreerealloc_zps246b76e3.png.html?sort= 3&o=2

4

2 回答 2

0

问题在于您的 for 循环。

在您的示例中, j 在第二个循环中等于 i+1 。i 有一个最大值 tracker - 1,所以 j 可以等于 tracker。这将导致您超出阵列,这可能会浪费内存。

尝试将它们更改为:

for (i = 0; i < tracker - 1; i++)
{
    for (j = 0; j < tracker - i - 1; j++)

另一个问题是,在您的内部循环中,您使用 [i] 和 [j] 来索引您的交换。如果将该循环中的每个 [i] 更改为 [j+1],您将获得一个有效的冒泡排序。

您的内部循环最终为:

      phone temp; /* I created a stack variable called temp - saves the need for allocation */

      for (i = 0; i < tracker - 1; i++)
{
    for (j = 0; j < tracker - i - 1; j++)
    {
        //Combines first and last names into 1 name for easy comparison
        strcpy(phonebook[j+1].totalname, phonebook[j+1].fName);
        strcpy(phonebook[j].totalname, phonebook[j].fName);
        strcat(phonebook[j+1].totalname, phonebook[j+1].lName);
        strcat(phonebook[j].totalname, phonebook[j].lName);
        printf("\nTotal name = %s\nTotal name = %s", phonebook[j+1].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
        if (strcmp(phonebook[j+1].totalname, phonebook[j].totalname) > 0)
        {
            strcpy(temp.fName, phonebook[j+1].fName);
            strcpy(temp.lName, phonebook[j+1].lName);
            temp.number = phonebook[j+1].number;
            temp.area = phonebook[j+1].area;

            strcpy(phonebook[j+1].fName, phonebook[j].fName);
            strcpy(phonebook[j+1].lName, phonebook[j].lName);
            phonebook[j+1].number = phonebook[j].number;
            phonebook[j+1].area = phonebook[j].area;

            strcpy(phonebook[j].fName, temp.fName);
            strcpy(phonebook[j].lName, temp.lName);
            phonebook[j].number = temp.number;
            phonebook[j].area = temp.area;
        }
    }
}
于 2013-10-24T06:12:37.210 回答
0

问题在于外循环。

如果您在数组中有“n”个条目进行排序,那么您必须将数组的第一个条目与剩余的“n-1”个条目进行比较。在将第一个条目与所有“n-1”个条目进行比较后,这意味着第一个条目正确地位于已排序数组中的位置。现在您留下了“n-1”个条目进行排序。现在,如果要比较数组的第二个条目,则必须将该第二个条目与剩余的“n-1-1”进行比较(仅剩下“n-1”个条目进行排序,并且您已将第二个条目与其余条目进行比较条目)。这一直持续到最后。

在您的代码中,您可以更改如下代码(循环部分): 注意:我创建了一个 temp 结构 phone 的 temp 变量。

    phone temp;
    for (i = 0; i < tracker - 1; i++)
    {
        for (j = i+1; j <= tracker - 1; j++)
        {
             //Combines first and last names into 1 name for easy comparison
             strcpy(phonebook[i].totalname, phonebook[i].fName);
             strcpy(phonebook[j].totalname, phonebook[j].fName);
             strcat(phonebook[i].totalname, phonebook[i].lName);
             strcat(phonebook[j].totalname, phonebook[j].lName);
             printf("\nTotal name = %s\nTotal name = %s", phonebook[i].totalname, phonebook[j].totalname); //Done so I can verify it worked correctly
             if (strcmp(phonebook[i].totalname, phonebook[j].totalname) > 0)
             {
                 strcpy(temp.fName, phonebook[i].fName);
                 strcpy(temp.lName, phonebook[i].lName);
                 temp.number = phonebook[i].number;
                 temp.area = phonebook[i].area;

                 strcpy(phonebook[i].fName, phonebook[j].fName);
                 strcpy(phonebook[i].lName, phonebook[j].lName);
                 phonebook[i].number = phonebook[j].number;
                 phonebook[i].area = phonebook[j].area;

                 strcpy(phonebook[j].fName, temp.fName);
                 strcpy(phonebook[j].lName, temp.lName);
                 phonebook[j].number = temp.number;
                 phonebook[j].area = temp.area;
             }
         }
     }
     printf("\n\nSuccessfully sorted!\n\n");
 }
于 2013-10-24T08:08:46.677 回答