このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1339338438/737
#  [1] 授業単元:C言語 
#  [2] 問題文(含コード&リンク): http://ime.nu/ideone.com/hx5VH 
#  
#  試験の各科目の点数を、受験者ごとに「出席番号 体育 美術 英語 数学 社会」の順番でテキストファイルに記録する。なお、出席番号は数字4桁、科目の点数は100点を満点とする。
#   
#   例:
#     0001 55 66 66 77 77
#     0002 44 55 33 44 33
#     0003 33 43 53 53 53
#                  . 
#                  .
#   
#  1,出席番号、各科目の点数を標準入力から入力し、上記のフォーマットにあわせて受験者の成績をファイルに記録するプログラムの作成。
#  なお出力ファイル名はコマンドライン引数で与えることとし、出席番号に数字以外の文字が入力された場合にデータの入力を終了せよ。
#   
#  2,作成したファイルを読み込み、受験者ごとの合計点、順位を求め「出席番号 合計点 順位」
#  の順にファイルに出力するプログラムを作成せよ。出力は成績順に並び替えなくとも良い。ただし、
#  入力ファイル名と出力ファイル名はコマンドライン引数で与えるものとする。
#   
#  ファイル処理について習いました。stdin やFILE構造体、書式付き入出力、
#  ブロック単位の入出力(size_t fwrite(const void *ptr, size_t size,size_t nmemb,FILE *stream) )
#  などを習いました

'作成したファイルを読み込み、受験者ごとの合計点、順位を求め「出席番号 合計点 順位」の順にファイルに出力する'(_入力ファイル,_出力ファイル) :-
        '作成したファイルを読み込み'(LL),
        '受験者ごとの合計点、順位を求め'(LL,LL3),
        '「出席番号 合計点 順位」の順にファイルに出力する'(_出力ファイル,LL3),!.

'作成したファイルを読み込み'(LL) :-
        get_split_lines(_入力ファイル,[' '],LL).

'受験者ごとの合計点、順位を求め'(LL,LL3) :-
        findall([_合計点,_出席番号],(
                    受験者ごとの(LL,_出席番号,_体育,_美術,_英語,_数学,_社会),
                    合計点(_体育,_美術,_英語,_数学,_社会,_合計点)),
                LL1),
        順位を求め(LL1,LL3).

受験者ごとの(LL,_出席番号,_体育,_美術,_英語,_数学,_社会) :-
        member([_出席番号,_体育,_美術,_英語,_数学,_社会],LL).

合計点(_体育,_美術,_英語,_数学,_社会,_合計点) :-
        _合計点 is _体育 + _美術 + _英語 + _数学 + _社会.

順位を求め(LL1,LL3) :-
        合計点の大きい順に(LL1,LL2),
        順位を張る(1,LL2,LL3).

合計点の大きい順に(LL1,LL2) :-
        sort(LL1,LL3),
        reverse(LL3,LL2).

順位を張る([],[]).
順位を張る(_順位,[[_合計点,_出席番号_1],[_合計点,_出席番号_2]|R1],[[_出席番号_1,_合計点,_順位]|R2]) :-
        順位を張る(_順位,[[_合計点,_出席番号_2]|R1],R2),!.
順位を張る(_順位,[[_合計点,_出席番号]|R1],[[_出席番号,_合計点,_順位]|R2]) :-
        _順位_2 is _順位 + 1,
        順位を張る(_順位_2,R1,R2).

'「出席番号 合計点 順位」の順にファイルに出力する'(_出力ファイル,LL) :-
        open(_出力ファイル,write,Outstream),
        append(_,[[_出席番号,_合計点,_順位]|R],LL),
        writef(Outstream,'%t %t %t\n',[_出席番号,_合計点,_順位]),
        R = [],
        close(Outstream).