qsort 创建非特定数量的零

Azz*_*ian 1 c zero qsort

所以我的程序从文件中读取整数,同时跳过以 开头的行,#然后将它们存储在一个数组中并使用该qsort函数将它们排序打印出来。但是,当它们被打印时,由于某种原因,它在开始时会打印一些零,然后是排序后的数字。如果数字对是 60,我得到 21 个零,如果数字对是 103688,它打印 60151 个零。

输入文件:

#Skip
#These
#Lines
25  8
25  19
25  23
25  28
25  29
25  30
25  33
25  35
25  50
25  54
25  55
Run Code Online (Sandbox Code Playgroud)

该计划是:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


typedef struct {
    int start;
    int end;   
} path;

int cmp(const void *a,const void *b){
    int l=((path*)a)->start;
    int r=((path*)b)->start;

    if(l>r)
        return 1;
    if(l<r)
        return -1;
    if(l==r)
        return 0;
}

int doublesize(path** array,int n){
    path* new_array=malloc(n*2*sizeof(path));
    if(new_array==NULL){
        printf("Error allocating memory\n");
        abort();
    }

    for(int i=0;i<n;i++){
        new_array[i]=(*array)[i];
    }
    free(*array);
    *array=new_array;
    n*=2;
    return n;
}

int main()
{
    int maxsize=10;
    int test;
    path* array=malloc(maxsize*sizeof(path));
    if(array==NULL) {
        printf("Error allocating memory\n");
        abort();
    }

    FILE* fd=fopen("Test.txt","r");
    if(fd==NULL) {
        printf("Error opening file\n");
        abort();
    }
    char buff[200];
    int counter=0;

    char c;
    while(fgets(buff,200,fd)) {
        c=buff[0];
        if(c=='#') {
            continue;
        }
        sscanf(buff,"%d%d",&array[counter].start,&array[counter].end);
        counter++;
        if(counter==maxsize){
           maxsize=doublesize(&array,maxsize); 
        }
    }
    counter=0;
    qsort(&array[0],maxsize,sizeof(path),cmp);
    for(int i=0;i<maxsize;i++){
        printf("%d\t%d\n",array[i].start,array[i].end);
        if(array[i].start==0)
            counter++;
    }
    printf("%d\n",counter);
    fclose(fd);
    free(array);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*lli 5

maxsize当您的数组仅包含counter元素时(在您的第一个while循环之后),您正在排序然后打印元素。您应该在排序和打印时使用准确的元素数量。

你看到很多的事实0只是一个巧合。当您使用 分配空间时malloc(),数组的内容是undefined,这意味着您没有明确覆盖的所有内容都将具有未定义的值(它可能是0或可能是另一个随机值)。排序时,所有0s 都将移到开头,但任何其他未定义(和 not 0)的内容实际上会出现在数据中间,可能与真实数据无法区分。

这不是qsort的错,而是 的malloc错(实际上最终是您的错)。

TL;DR:保留一个变量来保存数组中元素的确切数量,并且永远不会在该数字之后进行操作。

一个快速解决方案(我用 标记了修改^^^):

int total = 0;
//  ^^^^^
int counter = 0;
char c;

while(fgets(buff, 200, fd)) {
    if(buff[0] == '#')
        continue;

    sscanf(buff,"%d%d", &array[counter].start, &array[counter].end);
    total++;
//  ^^^^^

    if(total == maxsize)
//     ^^^^^
        maxsize = doublesize(&array, maxsize);
}

qsort(&array[0], total, sizeof(path), cmp);
//               ^^^^^

for(int i = 0; i < total; i++){
//                 ^^^^^
    printf("%d\t%d\n", array[i].start, array[i].end);

    if(array[i].start == 0)
        counter++;
}
Run Code Online (Sandbox Code Playgroud)