在Qsort中使用strcmp()比较字符串

时间:2019-01-25 15:12:46

标签: c string strcmp qsort

我目前正在countobjobjArray元素的descending order字段的objA.count字段中进行排序,如下面的程序所示,但我也希望我的程序检查objB.count中正在使用的两个当前cmpfunc()objb.word字段是否相等,然后检查objA.word字符串是否大于{{1} }字符串,如果可以,请交换它们。但是,使用下面包含的input.txt文件,您可以在输出中看到有些问题,您能帮我弄清楚那是什么吗?逻辑对我来说似乎是正确的,但也许我对cmpfunc()的工作方式或哪个字符串更大的字符串有误解。

Program.c:

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

/* PREPROCESSOR */
#define MAX_STRING_SIZE 512 /* each line in the file can have up to 512 chars */

/* Function Declarations */
void sortedCount(int,char **);
void *malloc_or_end(size_t);


/* Function Definitions */

/**
 * Allocates sz bytes of memory using malloc, checks if
 * the memory allocation was successfull and return a void* to the
 * beginning of the allocated memory.
 * */
void* malloc_or_end(size_t sz) {
  void *pointer;
  pointer = malloc(sz);
  if(pointer == NULL) {
    printf("Out of memory, terminating.\n");
    exit(-1);
  }
  return pointer;
}

/**
 * Function count: Prints the number of times
 * that the selected word is found inside the N first words
 * of the file.
 * */
int count(int N, char *word, int callID,char **wordList) {
    int i = 0;
    int count = 0;
    for(i = 0; i < N; i++) {
        if(strcmp(word,wordList[i]) == 0) {
            count++;
        }
    }
    if(callID == 0) { /* if callID == 0 (main called count and we want the output) */
        printf("%d",count);
        printf("\n");
    }
    return count;
}

typedef struct wordAndCount {
    int count;
    char *word;
} obj;

int cmpfunc(const void * a, const void * b) {
    obj objA = *(obj *)a;
    obj objB = *(obj *)b;
    int res = objA.count - objB.count;

    if(res > 0) {
        return -1;
    } else if(res < 0) { /* 2nd count is greater than the first */
        return 2;
    } else {
        int cmpResult = strcmp(objB.word,objA.word);
        if(cmpResult > 0) {
        } else if(cmpResult < 0) {
            /* do nothing */
            char *temp = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
            strcpy(temp,objA.word);
            strcpy(objA.word,objB.word);
            strcpy(objB.word,temp);
            free(temp);
        } else {
            /* do nothing */
        }
        return 0;
    }
}

void sortedCount(int N,char **wordList) {
    int i,j = 0;
    int *occurrences;
    obj *objArray;

    /* mem allocation */
    objArray = malloc_or_end(N * sizeof(obj));
    occurrences = malloc_or_end(N * sizeof(int));

    /* initialize occurrences for the "each word is unique and occurs only once" scenario */
    for(i = 0; i < N; i++) {
        objArray[i].word = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
        occurrences[i] = 1;
    }

    determineUniqueWords(occurrences,wordList,N);

    /* populate the wordCounts & uniqueWords "arrays" with the appropriate data in order to sort them successfully */
    for(i = 0; i < N; i++) {
        if(occurrences[i] > 0) {
            objArray[i].count = count(N,wordList[i],1,wordList);
            strcpy(objArray[i].word,wordList[i]);
        }
    }

    /* sort */
    qsort(objArray,N,sizeof(obj),cmpfunc);

    for(i = 0; i< N; i++) {
        if(objArray[i].count == 0 || (strcmp(objArray[i].word,"") == 0)) {
            continue;
        }
        printf("%d %s\n",objArray[i].count,objArray[i].word);
    }

    /* mem free */
    for(i = 0; i < N; i++) {
        free(objArray[i].word);
    }
    free(objArray);
    free(occurrences);
    return;
}

/* Stelios Papamichail AM 4020 */
int main(int argc,char *argv[]) { /* argv[1] = op argv[2] = name argv[3] = <word> */
    int N = -1;
    int i = 0;
    int spaceNum,nlNum = -1;

    FILE *file; 
    char **wordList; 


    file = fopen(argv[2],"r");

    if(file == (FILE *) NULL) { /* check if the file opened successfully */
        fprintf(stderr,"Cannot open file\n");
    }

    fscanf(file,"%d",&N); /* get the N number */

    wordList = malloc_or_end(N * sizeof(char *)); /* allocate memory for pointers */

    for(i = 0; i < N; i++) {
        wordList[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char)); /* allocate memory for strings */
    }

    populateWordsArray(N,wordList,file);

    if(strcmp(argv[1],"-reverse") == 0) {
        reverse(N,wordList);
    } else if(strcmp(argv[1],"-first") == 0) {
        first(N,wordList);
    } else if(strcmp(argv[1],"-middle") == 0) {
        middle(N,wordList);
    } else if(strcmp(argv[1],"-last") == 0) {
        last(N,wordList);
    } else if((strcmp(argv[1],"-count") == 0) && argv[3] != NULL) {
        i = count(N,argv[3],0,wordList);
    } else if((strcmp(argv[1],"-sorted") == 0) && (strcmp(argv[3],"-count") == 0)) {
        sortedCount(N,wordList);
    } else {
        /* i only wish i could print something here */
    }


    /* End of program operations */
    for(i = 0; i < N; i++) {
        free(wordList[i]);
    }
    free(wordList);
    fclose(file);
    return 0;
}

Input.txt:

11 this is a simple text is a a z z z

输出:

3 a
3 z
2 is
1 simple
1 text
1 this

预期输出:

3 z
3 a
2 is
1 simple
1 this
1 text

1 个答案:

答案 0 :(得分:1)

您的比较功能不应操纵被比较的对象。 您只能返回比较结果:

int cmpfunc(const void * a, const void * b)
{
    obj *objA = (obj *)a;
    obj *objB = (obj *)b;

    int res = objA->count - objB->count;
    // negative value means A is less than B.

    if(res == 0)
    {
        res = strcmp(objA->word, objB->word);
        // negative value if A is less than B.
    }

    return res; // or -res for other sorting direction
}

当您可以使用指针直接在数组中访问它们时,也无需复制函数中的元素。