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

Comparing strings using strcmp() in qsort

我目前正在对 descending orderobjArrayobj 元素的 count 字段进行排序,如您在下面的程序中所见,但我也想要我的程序检查 cmpfunc() 中使用的两个当前 objA.countobjB.count 字段是否相等,然后检查 objb.word 字符串是否大于 objA.word 字符串,如果是这样交换它们。但是,使用我在下面包含的 input.txt 文件,您可以在输出中看到某些东西不是 working.Can,您能帮我弄清楚那是什么吗?这个逻辑对我来说似乎是正确的,但也许我误解了 cmpfunc() 的工作原理或哪个字符串是 "bigger".

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

您的比较函数不应该操作被比较的对象。 你只能return一个比较结果:

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
}

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