現在C言語を用いて、コマンドライン引数で受け取ったファイルを読み取り、連結リストとして出力ファイルに書き込むプログラムを実装しました。
これに加えて、このファイル要素を昇順にソートしたいと考えています。
入出力のプログラム
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct school_record SRec; struct school_record{ float gpa;/*累積GPA*/ int credit;/*累積単位数*/ char name[200];/*名前(アルファベット)*/ SRec *next; /*次のセルへのポインタ*/ }; SRec *p;/*連結リストをたどるためのポインタ*/ SRec *input_file(char *input_name); void output_file(char *output_name,SRec *front); int main(int argc,char *argv[]) {/*agrv[1]はソートを行うフィールド名(メンバ名)※この課題では必要なし、[2]は入力ファイル名:データ件数は記録しない、[3]は出力ファイル名*/ // int n,i; SRec *front; if(argc != 4){/*ファイルは3つ(プログラム名を含めて4つ)*/ printf("ソートを行いたいフィールド名、入力ファイル、出力ファイルの3つをコマンドライン引数で指定してください.\n"); return 1; } front = input_file(argv[2]);/*入力処理を行う*/ output_file(argv[3],front); return 0; } SRec *input_file(char *input_name){/*入力ファイル名を受け取りファイルをオープンして、データ領域を確保し、一件分のデータ入力と挿入を繰り返す、先頭要素へのポインタを返す*/ int credit_temp; float gpa_temp; char name_temp[200];/*ファイル読み込みのための一時変数*/ SRec header;/*連結リスト自身を表すためのダミー*/ SRec *p;/*連結リストをたどるためのポインタ*/ SRec *tail = &header;/*初期化、連結リストの最後の要素*/ header.next = NULL; FILE *fp; if((fp = fopen(input_name,"r")) == NULL){/*ファイルをオープン*/ printf("入力ファイルをオープンできませんでした。\n"); } while(fscanf(fp,"%f %d %s ",&gpa_temp,&credit_temp,name_temp)==3){/*ファイルの内容を読み込んで一時変数に格納する*/ /*連結リストに関するif文*/ if((p=malloc(sizeof(SRec)))==NULL){ printf("メモリが足りません。"); exit(1); } p->gpa = gpa_temp; p->credit = credit_temp; strcpy(p->name,name_temp);/*連結リストに値を入れる*/ printf("%f %d %s\n",p->gpa,p->credit,p->name);/*デバッグ用*/ p->next = NULL; tail->next = p; tail = p; /*セルを進める*/ } fclose(fp); printf("入力ファイルの処理完了。\n"); return header.next; } void output_file(char *output_name, SRec *front){/*出力ファイル名と連結リストの先頭へのポインタを受け取り、書き込む*/ FILE *fp; if((fp = fopen(output_name,"w")) == NULL){ printf("出力ファイルをオープンできませんでした。\n"); } while(front != NULL){ fprintf(fp,"%f %d %s\n",front->gpa,front->credit,front->name); front = front->next; } printf("書き込みに成功しました。\n"); fclose(fp); free(p); }
これに以下のようなプログラムを加えて昇順のソートをしたいと考えています。
・dummyはリストが空にならないために定義する
・最初、qはdummyを指しpはその次のfront(引数で受け取ったリストの最初の要素)を指す
・比較関数にqとpを送り比較してもらい、昇順になっていなければソートを行う←このソートの部分の実装方法がわかりません
・qとpをがNULLを指すまで順次ひとつずつずらしていく(探索していく)
・戻り値としてリストの先頭を返し、output_file関数で出力ファイルに書き込めるようにする
SRec *list_sort(SRec *front,int (*comp)(const void*,const void*)){ SRec dummy; SRec *p,*q; dummy.next = front; q = &dummy; p = q->next; while(p != NULL){ if( comp(q,p)>=0 ){ /*q->nextに挿入する*/ p->next = q->next; break; } q = p; p = p->next; /*リストを進める*/ } return front;/*pでもいいのか??*/ }
ソートプログラムを実現したいのですが、if文中でのソートの実装方法がわからないため、ご教授いただきたいです。
回答4件
あなたの回答
tips
プレビュー