在 qsort 中使用 strcmp() 比较字符串
Comparing strings using strcmp() in qsort
我目前正在对 descending order
中 objArray
中 obj
元素的 count
字段进行排序,如您在下面的程序中所见,但我也想要我的程序检查 cmpfunc()
中使用的两个当前 objA.count
和 objB.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
}
当您可以使用指针直接访问数组中的元素时,也无需复制函数中的元素。
我目前正在对 descending order
中 objArray
中 obj
元素的 count
字段进行排序,如您在下面的程序中所见,但我也想要我的程序检查 cmpfunc()
中使用的两个当前 objA.count
和 objB.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
}
当您可以使用指针直接访问数组中的元素时,也无需复制函数中的元素。