我尝试使用qsort
函数按字母顺序从文件中读取的字符串数组。这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<io.h>
#define MAXCHAR 256
int main(int argc, char **argv){
char tempList[MAXCHAR][MAXCHAR];
char reader[MAXCHAR];
FILE* fp;
int i;
char *n;
int index = 0;
if(argc != 2){
printf("too few arguments\n");
exit(-1);
}
fp=fopen(argv[1], "r");
if(fp == NULL){
printf("failed to open file\n");
exit(-1);
}
while(!feof(fp)){
fgets(reader, MAXCHAR, fp);
n = strchr(reader, '\n');
if(n != NULL){
*n = '\0';
}
strcpy(tempList[index], reader);
index++;
}
index--;
for(i=0; i<index; i++){
printf("%s\n", tempList[i]);
}
qsort(tempList, index, sizeof(char *), strcmp);
for(i=0; i<index; i++){
printf("%s\n", tempList[i]);
}
}
当我运行程序时,列表根本没有排序。我也试过在这个网站上发布的方法,提出了类似的问题,他们都给我分段错误。代码有问题吗?
以下是txt文件内容的一部分。它是40个名字的列表:
Liam
Alexander
Mia
Noah
Emma
William
Charlotte
Charlotte
Mason
William
Ethan
Ethan
Liam
Alexander
Liam
Sophia
Emily
Mason
Alexander
答案 0 :(得分:3)
你有一个真正的数组阵列;不是char*
的数组。数组不是指针。 qsort
期望序列中元素的 stride 被排序。当您的序列声明为:
char tempList[MAXCHAR][MAXCHAR];
适当的元素大小是劣质元素大小的大小。在这种情况下,您有一个大小为MAXCHAR
的数组char
的数组,其大小为MAXCHAR
(数组数组)。
因此这是错误的:
qsort(tempList, index, sizeof(char *), strcmp);
// wrong size ==============^^^^
每个元素的大小应为:
qsort(tempList, index, sizeof tempList[0], strcmp);
// correct size ==============^^^^
你的程序中的其他问题最终会让你感到悲伤,并且在你的问题下面的一般评论中有所涉及,但这是阻止你的排序正常工作的根本问题。下面是一个重新编写的程序版本,解决了大多数问题:
更新来源
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHAR 256
/* properly declared for compatibility with qsort */
static int cmp_str(const void *lhs, const void *rhs)
{
return strcmp(lhs, rhs);
}
/* main entrypoint */
int main(int argc, char **argv)
{
char tempList[MAXCHAR][MAXCHAR];
FILE* fp;
size_t i, index = 0;
if(argc != 2)
{
printf("too few arguments\n");
return EXIT_FAILURE;
}
fp=fopen(argv[1], "r");
if(fp == NULL)
{
perror(argv[1]);
return EXIT_FAILURE;
}
while(index < MAXCHAR && fgets(tempList[index], sizeof(*tempList), fp) != NULL)
{
char *n = strchr(tempList[index], '\n');
if(n != NULL)
*n = 0;
if (*(tempList[index])) /* don't insert blank lines */
++index;
}
for(i=0; i<index; i++)
printf("%s\n", tempList[i]);
fputc('\n', stdout);
qsort(tempList, index, sizeof tempList[0], cmp_str);
for(i=0; i<index; i++)
printf("%s\n", tempList[i]);
return EXIT_SUCCESS;
}
未经测试,但它应该非常接近。
祝你好运。
答案 1 :(得分:2)
qsort(tempList, index, sizeof(char *), strcmp);
中的尺码值错误。
它应该是qsort(tempList, index, sizeof(*tempList), strcmp);
。
答案 2 :(得分:1)
我试图修复你的代码。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<io.h> it's not standart
#define MAXCHAR 256
// I implement the function because the warning is that
// Incompatible pointer types passing 'int
// (const char *, const char *)' to parameter of type
// 'int (*)(const void *, const void *)'
// Already qsort() prototype is
// void qsort(void* ptr, size_t count, size_t size,
// int (*comp)(const void*, const void*));
// I think that the warning can be ignored strcmp also can be used
int myCompare(const void* a, const void* b)
{
const char* aa = (const char*)a;
const char* bb = (const char*)b;
return strcmp(aa, bb);
}
int main(int argc, char **argv){
char tempList[MAXCHAR][MAXCHAR];
char reader[MAXCHAR];
FILE* fp;
int i;
char *n;
int index = 0;
if(argc != 2){
printf("too few arguments\n");
exit(-1);
}
fp=fopen(argv[1], "r");
if(fp == NULL){
printf("failed to open file\n");
exit(-1);
}
while(fgets(reader, MAXCHAR, fp) != NULL){ // !feof is not recommended search why
n = strchr(reader, '\n');
if(n != NULL){
*n = '\0';
}
strcpy(tempList[index], reader);
index++;
}
/*
printf("%lu\n",sizeof(reader)); //256
printf("%lu\n",sizeof(*reader)); //1
printf("%lu\n",sizeof(*tempList)); //256
printf("%lu\n",sizeof(**tempList)); //1
*/
for(i=0; i<index; i++){
printf("%s\n", tempList[i]);
}
qsort(tempList, index, sizeof(*tempList), myCompare);
printf("\n\nAfter sorting\n\n");
for(i=0; i<index; i++){
printf("%s\n", tempList[i]);
}
}