0

related post: C qsort not working as intended, erasing elements?

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define MAXS    128
#define MAXB    32
typedef struct info{
    char name[MAXB];
    char address[MAXB];
    char citystate[MAXB];
    char zip[MAXB];
}info;

int compare(const void *s1,const void *s2);

int main(int argc, char *argv[])
{
    int idx = 0;
    info *addr[MAXS] =  {NULL};
    FILE *fp = NULL;

    if(argc != 3){
        fprintf(stderr,"usage: program, inputfile, outputfile\n");
        exit(EXIT_FAILURE);
    }
    
    if((fp = fopen(argv[1],"r")) == NULL){
        fprintf(stderr,"input file cannot open\n");
        exit(EXIT_FAILURE);
    }

    for(idx = 0; idx < MAXS;){
        int a1, a2,a3,a4;
        char buf[MAXB] = "";
        info tmp =  {.name = ""};
        
        if(!fgets(buf, MAXB,fp)) break; /* read/validate lines */
        a1 = ((buf[MAXB-2] && buf[MAXB-2] != '\n') ||
            !sscanf(buf,"%31[^\n]", tmp.name));

        if(!fgets(buf, MAXB,fp)) break; /* read/validate lines */
        a2 = ((buf[MAXB-2] && buf[MAXB-2] != '\n') ||
            !sscanf(buf,"%31[^\n]", tmp.address));

        if(!fgets(buf, MAXB,fp)) break; /* read/validate lines */
        a3 = ((buf[MAXB-2] && buf[MAXB-2] != '\n') ||
            !sscanf(buf,"%31[^\n]", tmp.citystate));

        if(!fgets(buf, MAXB,fp)) break; /* read/validate lines */
        a4 = ((buf[MAXB-2] && buf[MAXB-2] != '\n') ||
            !sscanf(buf,"%31[^\n]", tmp.zip));
        
        if(a1 || a2 || a3 || a4) continue;

        if(!(addr[idx] = malloc(sizeof *addr[idx]))){
            fprintf(stderr,"error: no mem\n ");
            exit(EXIT_FAILURE);
        }
        /* copy tmp to addr[idx] and increment index */
        memcpy(addr[idx++],&tmp, sizeof tmp);
    }

    fclose(fp);
    printf("idx=%d\n",idx);
    for(int t = 0; t<idx; t++){
        printf("%-8s\t%-22s\t%-20s\t%s\n"
            ,addr[t]->name,addr[t]->address
            ,addr[t]->citystate,addr[t]->zip
        );
    }
    printf("\n\n");
    qsort(addr,MAXS,sizeof *addr,compare);
    for(int t = 0; t<idx; t++){
        printf("%-8s\t%-22s\t%-20s\t%s\n"
            ,addr[t]->name,addr[t]->address
            ,addr[t]->citystate,addr[t]->zip
        );
    }
    exit(EXIT_SUCCESS);
}

int compare(const void *s1,const void *s2)
{
    const struct info* e1 = s1;
    const struct info* e2 = s2;
    // int temp = strcmp(addr[0]->zip,addr[1]->zip);
    // printf("|%s|vs|%s|= %d\n",e1->zip,e2->zip, (strcmp(e1->zip,e2->zip)));
    if(e1->zip < e2->zip) return -1;
    if(e1->zip > e2->zip) return 1;
    return 0;
    // return strcmp(e1->zip, e2->zip);
}

structaddr.txt file content:

A1, A2
20294 Lorenzana Dr
Woodland Hills, CA
91364
B1, B2
19831 Henshaw St
Culver City, CA
94023
C1, C2
5142 Dumont Pl
Azusa, CA
91112
D1, D2
20636 De Forest St
Woodland Hills, CA
91364

compile it:

gcc -Wall -Wextra -O3 -pedantic -Wshadow -Ofast \
    -Wno-declaration-after-statement \
    test.c   \
    && ./a.out dat/structaddr.txt dat/structaddrout.txt

qsort before and after, printf output is the same. In compare function, also tried return strcmp(e1->zip, e2->zip); ,but still the printf return (twice) is the same. expected sort order by zip, 91112, 91364, 94023.

jian
  • 4,119
  • 1
  • 17
  • 32

0 Answers0