我不知道为什么我的程序不能在vi上正确编译。它只打印第一次出现的函数show(var),然后退出并列出分段错误和核心转储,但是,它在emacs上编译时没有任何错误,并在快速排序后显示所有字符串。
该程序应该从我存储在同一目录中的文本文件中读取数据,并使用2个比较函数中的一个对其进行快速排序(这不一定有意义,它们只需要起作用),然后将其打印到屏幕上。
提前谢谢。
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
void show(void *array[]){
int i = 0;
while(array[i]!=NULL){
printf("String %d : %sn",i, array[i]);
i++;
}
printf("n");
}
void *readData(void * lineArray[]){
static const char filename[] = "sampledata.txt";
FILE *file = fopen ( filename, "r" );
if ( file != NULL )
{
int i ;
char line [ 128 ]; /* or other suitable maximum line size */
void *lineadrs ;
i = 0;
lineadrs = malloc(sizeof(void) * 1024);
while ( fgets ( lineadrs, sizeof line, file ) != NULL ) /* read a line */
{
lineArray[i] = lineadrs;
lineadrs = malloc(sizeof(void) * 1024);
i++;
}
fclose ( file );
}
else {
perror ( filename );
return 0;
}
return lineArray ;
}
void swap(void *v[], int i, int j)
{
void *temp;
temp = v[i];
v[i] = v[j];
v[j]=temp;
}
//normal compare
int cmp1 (void *first_arg, void *second_arg)
{
if ( *(char*)first_arg < *(char*)second_arg )
{
return -1;
}
if ( *(char*)first_arg == *(char*)second_arg )
{
return 0;
}
else {
return 1;
}
}
//reverse the compare
int cmp2 (void * a, void * b)
{
char *ia = (char *)a; // casting pointer types
char *ib = (char *)b;
return *ib - *ia;
//return ( *(int *)b + *(int *)a );
}
void QSort(void *v[],int left, int right, int (*compare)(void *first, void *second))
{
int i, last;
void swap (void *v[],int ,int);
if(left >= right){
return;
}
swap(v,left,(left+right)/2);
last=left;
for(i=left+1;i<=right; i++){
if((*compare)(v[i],v[left])<0){
swap(v,++last,i);
}
}
swap(v,left,last);
QSort(v,left,last-1,compare);
QSort(v,last+1,right,compare);
}
int main(){
void * var[6];
readData(var);
printf("Original String:n");
show(var);
QSort(var,0,4,cmp1);
printf("After cmp 1 which compares alphabetically.n");
show(var);
QSort(var,0,4,cmp2);
printf("After cmp 2 which compares reverse alphabetically.n");
show(var);
return 0;
}
这段代码中的错误列表太多了,无法提及
- 线阵列是固定的。它应该是动态的。读取超过4行的文本将超过输入数组的长度,从而调用未定义的行为
- 比较器对于字符串内容是错误的
- 内存泄漏很多
我相信,下面的代码就是你想要做的。我真诚地希望你花时间从中学习。还有几件事需要做,但区别已经是白天和黑夜了。我应该警告你,我是在网上写的,没有给它测试时间,但它应该是正确的。由于我没有你的示例数据,这就是我所能做的。祝你好运。
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// read data from a named file one line at a time, storing each
// in a ever-expanding line array. The return result is the
// number of lines allocated. The resulting line array is passed
// as an output parameter
int readData(const char filename[], void ***results)
{
// default answer: no lines, zero-length
void **lines = NULL;
int i=0;
FILE *file = fopen ( filename, "r" );
if ( file != NULL )
{
char line [ 128 ];
while ( fgets ( line, sizeof line, file ) != NULL )
{
// trim the newline from line buffer
size_t slen = strlen(line);
if (slen > 0 && line[slen-1] == 'n')
line[--slen] = 0;
// resize lines array
void **new_lines = realloc(lines, (i+1)*sizeof(*new_lines));
if (new_lines == NULL)
{
perror("Failed to realloc lines array.");
exit(EXIT_FAILURE);
}
// save new line entry, terminate with NULL;
lines = new_lines;
lines[i++] = strdup(line);
}
fclose ( file );
}
else
{
perror(filename);
exit(EXIT_FAILURE);
}
// setup output result and return value
*results = lines;
return i;
}
// display an array of a specified length
void show(void *array[], int len)
{
int i=0;
for (; i<len; ++i)
printf("String %d : %sn", i, array[i]);
printf("n");
}
//normal compare
int cmp1 (void *first_arg, void *second_arg)
{
return strcmp((const char*)first_arg, (const char*)second_arg);
}
//reverse the compare
int cmp2 (void *first_arg, void *second_arg)
{
return strcmp((const char*)second_arg, (const char*)first_arg);
}
// swap to void* by address
void swap(void **lhs, void **rhs)
{
void *tmp = *lhs;
*lhs = *rhs;
*rhs = tmp;
}
// the simplest quicksort I can fathom
void QSort(void *v[], int len, int (*compare)(void*, void*))
{
if (len < 2)
return;
// swap random element to last slot
swap(v+(rand() % len), v+(len-1));
// partition around the pivot value
int pvt=0,i;
for (i=0; i<len; ++i)
{
if (compare(v[i], v[len-1]) < 0)
swap(v+i, v+pvt++);
}
// swap pivot into place
swap(v+pvt, v+(len-1));
// recurse. note the pivot slot is skipped.
QSort(v, pvt++, compare);
QSort(v+pvt, len-pvt, compare);
}
int main()
{
static const char filename[] = "sampledata.txt";
srand((unsigned)time(NULL));
void **var = NULL;
int len = readData(filename, &var);
if (len > 0)
{
printf("Original String:n");
show(var, len);
QSort(var, len, cmp1);
printf("After cmp 1 which compares alphabetically.n");
show(var, len);
QSort(var, len, cmp2);
printf("After cmp 2 which compares reverse alphabetically.n");
show(var, len);
// release lines when finished
while (len-- != 0)
free(var[len]);
free(var);
}
return 0;
}