2011-05-25 251 views
0

所以我使用C,我似乎无法得到这个工作正确。它是包含一些联系信息的结构体的指针数组。我似乎无法得到qsort排序正确。 这里是我的代码qsort不排序和奇怪的输出

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX 20 
#define ELEMENTS 50 

int sortZips(const void *a, const void *b); 

typedef struct contactInfo { 
char name[MAX]; 
char street[MAX]; 
char cityState[MAX]; 
char zipCode[MAX]; 
} contacts; 


int main() { 
int i = 0; 
contacts **contactArray = malloc(ELEMENTS * sizeof(contacts *));  

/* allocate array */ 
for (i = 0; i < ELEMENTS; i++) { 
    contactArray[i] = malloc(sizeof(contacts)); 
} 
/* populate array */ 
for (i = 0; i < ELEMENTS; i++) { 
    fgets(contactArray[i]->name,MAX,stdin); 
    fgets(contactArray[i]->street,MAX,stdin); 
    fgets(contactArray[i]->cityState,MAX,stdin); 
    fgets(contactArray[i]->zipCode,MAX,stdin); 

    printf("%s", contactArray[i]->name); 
    printf("%s", contactArray[i]->street); 
    printf("%s", contactArray[i]->cityState); 
    printf("%s", contactArray[i]->zipCode); 

} 
printf("\n"); 


/* qsort((void *)contactArray, ELEMENTS, sizeof(contacts *), sortZips); */ 


for (i = 0; i < ELEMENTS; i++) { 
    fputs(contactArray[i]->name,stdout); 
    fputs(contactArray[i]->street,stdout); 
    fputs(contactArray[i]->cityState,stdout); 
    fputs(contactArray[i]->zipCode,stdout); 
} 


} 


/* sortZips() sort function for qsort */ 

int sortZips(const void *a, const void *b) { 

const contacts *ia = *(contacts **)a; 
const contacts *ib = *(contacts **)b; 
return strcmp(ia->zipCode, ib->zipCode); 



} 

输出打印地址(我有50个输入文件),然后一些随机字符,像他们这样的一个巨大的块,然后排序列表之后被搞砸并没有排序的权利。

请任何帮助,将不胜感激。我需要知道这里出了什么问题,为什么。 Thanx。

回答

0

第一条规则:总是检查输入函数 - 在这种情况下,fgets()。如果你不检查,你不知道一切工作是否正常。

第二:通常使用enum优先于#define

随着早期EOF的检查到位,您的代码将我的样本数据(6行)完整地排序。它也编译干净 - 这是非常不寻常的(这是一种赞美;我使用严格的警告,甚至我的代码很少第一次干净地编译)。我修改代码的版本非常相似,你的:

int main(void) 
{ 
    int i = 0; 
    int num; 
    contacts **contactArray = malloc(ELEMENTS * sizeof(contacts *)); 

    /* allocate array */ 
    for (i = 0; i < ELEMENTS; i++) 
     contactArray[i] = malloc(sizeof(contacts)); 

    /* populate array */ 
    for (i = 0; i < ELEMENTS; i++) 
    { 
     if (fgets(contactArray[i]->name,MAX,stdin) == 0 || 
      fgets(contactArray[i]->street,MAX,stdin) == 0 || 
      fgets(contactArray[i]->cityState,MAX,stdin) == 0 || 
      fgets(contactArray[i]->zipCode,MAX,stdin) == 0) 
      break; 
     printf("%s", contactArray[i]->name); 
     printf("%s", contactArray[i]->street); 
     printf("%s", contactArray[i]->cityState); 
     printf("%s", contactArray[i]->zipCode); 
    } 
    printf("\n"); 
    num = i; 

    qsort(contactArray, num, sizeof(contacts *), sortZips); 

    for (i = 0; i < num; i++) 
    { 
     fputs(contactArray[i]->name,stdout); 
     fputs(contactArray[i]->street,stdout); 
     fputs(contactArray[i]->cityState,stdout); 
     fputs(contactArray[i]->zipCode,stdout); 
    } 
    return 0; 
} 

我所用的数据是这样的台4线琐碎重复:

First LastName7 
7 Some Street 
City, CA 
95437 

注意,“错误检查“我在输入中只是最低限度的”有效“。如果在输入中出现超长线,则一个字段将不包含换行符,而下一个将包含输入行的下一部分(可能所有其余部分,可能不包括 - 这取决于行的长度是多少)。

+0

是啊我看到我应该专注于输入功能,看看混乱开始的地方。我正在考虑这种排序,以及我是否正确地访问了结构的成员。这让我感到困惑。在此之前,我从来没有使用过qsort,并且在将void *传递给排序函数的过程中遇到了一些麻烦。 – Hasen 2011-05-25 04:56:11

0

如果您的地址在最后打印出垃圾,那几乎肯定是因为您没有为它们分配足够的空间。二十个字符对地址偏低。

什么是可能发生的事情是,你有一个像地址:

14237 Verylongstreetname Avenue 

,当你做fgets (street,20,stdin);,只有14237 Verylongstree将被读取(19个字符,留出空间为空终止)。

而且,这里是关键:文件指针仍然指向tname Avenue位,因此,当您尝试阅读cityState时,您会看到。而且,当您尝试阅读zipCode时,您将获得cityState一行,从而有效填充您的排序。

+0

好的,谢谢你的回应,但是我还没有意识到有一件真正愚蠢的事情!并解决了问题,输入文件没有50个联系人的输入值。 18岁时,将'ELEMENTS'设置为18来解决问题,我也将'MAX'提升到了40,以防万一。所以我认为发生了什么事情是我为“contactArray”分配了50个元素,并放置了18个元素的数据,并将其余的随机废话放在其余的地方并打印出来。 – Hasen 2011-05-25 04:44:23

0

我相信你有足够的空间。因为你正在使用fgets和MAX的大小,所以应该剪切字符串以适应并在最后具有终止NUL。

两件事情,可能会搞乱起来:

  • 与fgets将从它停止阅读,如果线太长阅读。这会导致“这太长了”的地址,“它会被剪切\ n”。然后其余的输入将会遍布整个地方。
  • 如果您没有足够的输入来填充ELEMENTS项目,那么您将获得malloc'd内存中的任何随机数据。如果您要使用calloc,它会为您调零内存。虽然更好的想法是使用一个计数器来记录实际读取的项目数量,而不是假定会有ELEMENTS项目。