ファイルの中身は
3.5 27 jiro
2.7 24 taro
3.7 30 saburo
です
ソート方法は、ソート前のリスト:L, ソート後のリスト:S
1. Lが空なら終了
2. Lの中の最大要素Mを探索
3. MをLから削除
4. MをSに挿入( 挿入はSの先頭に)
5. 1. へ
というかんじです。
今回は結構自分で考えてやってみたのですが、出力ファイルに何も表示されません。。。
どなたか力をかしてくださいお願いしますm(__)m
下にコードをはります。不明な点などあれば言ってください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct school_record SRec;
struct school_record {
float gpa;
int credit;
char name[200];
SRec *next;
};
SRec head; // head.next がリストの先頭要素を指す
SRec* listsort(SRec *node,int (*func)(const void *,const void *))
{
SRec top; //top.nextがソート後のリストの先頭要素へのポインタ
SRec *save1,*save2,*p,*list,*last; //topの末尾がlast
//listはソート後のmalloc
top.next=NULL;
node=top.next;
last=⊤
while(p->next!=NULL)
{
p=&head;
list = (SRec *) malloc(sizeof(SRec));
list->next=NULL;
if(list==NULL)
{
fprintf(stderr,"メモリ不足");
return NULL;
}
while(p->next!=NULL)
{
if(func(p->next,p)==1) //最大のものを検索
{
save1=p; //削除するために最大のものの1つ手前をsave1として覚える
save2=p->next; //最大のものをsave2
p=p->next;
}
}
save1->next=save1->next->next; //リストの削除
list=save2;
list->next=top.next;
top.next=list;
}
free(list);
return top.next;
}
int compare_float(const void * a, const void * b)
{
SRec* tmp1 = (SRec*) a;
SRec* tmp2 = (SRec*) b;
if (tmp1->gpa == tmp2->gpa)
return 0;
else if (tmp1->gpa > tmp2->gpa)
return 1;
else
return -1;
}
int compare_int(const void* a, const void* b)
{
SRec* tmp1 = (SRec*) a;
SRec* tmp2 = (SRec*) b;
if (tmp1->credit == tmp2->credit)
return 0;
else if (tmp1->credit > tmp2->credit)
return 1;
else
return -1;
}
int compare_char(const void * a, const void * b)
{
SRec* tmp1 = (SRec*) a;
SRec* tmp2 = (SRec*) b;
if (strcmp(tmp1->name, tmp2->name) == 0)
return 0;
else if (strcmp(tmp1->name, tmp2->name) == 1)
return 1;
else
return -1;
}
SRec* Input(FILE* fpi)
{
SRec *node;
SRec *tail;
head.next = NULL;/*これが NULL だとリストにはまだ 1つもノードがないことを表す。
これが NULL でないとリストに最低 1つはノードがあることになる。
実際にはまだリストは空っぽだから NULL する。*/
tail = &head;
while (1)
{
node = (SRec *) malloc(sizeof(SRec));//これは配列ではない
if (node == NULL)
{
fprintf(stderr,"メモリ不足");
return NULL;
}
if (fscanf(fpi, "%f%d%s", &node->gpa, &node->credit, node->name) != 3)
{
break; // 読み込みに失敗したら EOF (feof は使わないほうがよい)
}
node->next = NULL; // この node を末尾要素とする
for (tail = &head; tail->next != NULL; tail = tail->next) ;// 現在のリストの末尾要素を探す
tail->next = node; // 見つかった末尾要素に node を追加する。
}
free(node);
return head.next; // リストの先頭要素へのポインタを返す。
}
void Output(SRec *node, FILE* fpo)
{
for (; node != NULL; node = node->next)
{
fprintf(fpo,"%3.1f %d %s\n", node->gpa, node->credit, node->name);
}
}
int main(int argc, char *argv[])
{
SRec* node;
FILE *fpi, *fpo;
int (*func)(const void*,const void*);
if (argc != 4)
{
fprintf(stderr, "Illegal number of argument.\n");
return (-1);
}
if ((fpi = fopen(argv[2], "r")) == NULL)
{
fprintf(stderr, "Can't open input file <%s>.\n", argv[2]);
return (-1);
}
if ((fpo = fopen(argv[3], "w")) == NULL)
{
fprintf(stderr, "Can't open output file <%s>.\n", argv[3]);
return (-1);
}
node = Input(fpi);
if (strcmp(argv[1], "gpa") == 0)
func=compare_float;//&はどちらでもいい
else if (strcmp(argv[1], "credit") == 0)
func=compare_int;
else if (strcmp(argv[1], "name") == 0)
func=compare_char;
listsort(node,func);
if (node == NULL) return 1;
Output(node, fpo);
fclose(fpi);
fclose(fpo);
return 0;
}