?- 'a##'. c157-938#
このディレクトリの索引
http://toro.2ch.net/test/read.cgi/tech/1335517816/938
#  [1] 授業単元: コンピュータプログラミング  
#  [2] 問題文(含コード&リンク): http://ime.nu/ideone.com/qvNtf 
#  2
#  [問2] 国語と数学の2科目のテストの成績を処理するプログラムを作る。成績を3人分キーボードから入力した後、それを表示したい。これについて、次の手順でkadai7-2.cを作成しなさい。
#   1)次の構造体を利用する。
#   
#  struct SEISEKI {
#       char name[50];
#       int kokugo;
#       int sugaku;
#   };  <ーセミコロンを忘れないように(慣れた人でも良く間違う)
#   
#  2) 次の配列を用意する。
#  struct SEISEKI score[3];
#   
#   3) main関数で上記score[3]に次のようにデータをキーボード入力するようにする。
#  scanf("%s %d %d %s %d %d %s %d %d", 一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....);
#  注意:上記「一人目の氏名」とは、score[0].nameのことです。またscanfの使いかたとして文字列には&は要りませんが、int型やdouble型の変数の場合には頭に&を付けないといけません。
#  ex. 入力例:
#  yamauchi 60 70 yamada 80 90 tougou 70 80
#   
#   4)次の関数を定義する。
#  void print_score(struct SEISEKI a);
#  この関数は次のように成績を出力するものとする。
#  printf(" name: %s\n kokugo: %d\n sugaku: %d\n", ........);
#  表示例:
#   name:  yamauchi
#    kokugo: 60
#    sugaku: 70
#   
#   5) void print_score()を使って3人分の成績を列挙する。

'国語と数学の2科目のテストの成績を処理するプログラムを作る。成績を3人分キーボードから一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....のように一行で入力した後、それを表示する' :-
        '成績を3人分キーボードから一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....のように一行で入力した後'(_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績),
        それを表示する([_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績]).

'成績を3人分キーボードから一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....のように一行で入力した後'(_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績) :-
        write('一行に 氏名,国語の成績,数学の成績,の形式で三人分入力してください\n'),
        項目ならび([_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績]),
        入力検査([_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績],正常終了),!.
'成績を3人分キーボードから一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....のように一行で入力した後'(_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績) :-
        '成績を3人分キーボードから一人目の氏名, 一人目の国語の成績, 一人目の数学の成績, 二人目の氏名, 二人目の国語の成績,....のように一行で入力した後'(_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績).

入力検査([_一人目の氏名,_一人目の国語の成績,_一人目の数学の成績,_二人目の氏名,_二人目の国語の成績,_二人目の数学の成績,_三人目の氏名,_三人目の国語の成績,_三人目の数学の成績],_診断) :-
        整数項目入力検査([_一人目の国語の成績,_一人目の数学の成績,_二人目の国語の成績,_二人目の数学の成績,_三人目の国語の成績,_三人目の数学の成績],[_一人目の国語の成績,_一人目の数学の成績,_二人目の国語の成績,_二人目の数学の成績,_三人目の国語の成績,_三人目の数学の成績],_診断),!.

整数項目入力検査([],[],異常終了) :- !,fail.
整数項目入力検査([],[],正常終了) :- !.
整数項目入力検査([_科目名|R1],[_成績|R2],_診断) :-
        integer(_成績),
        整数項目入力検査(R1,R2,_診断),!.
整数項目入力検査([_科目名|R1],[_成績|R2],異常終了) :-
        writef('%tが正しく入力されませんでした。\n',[_科目名]),
        整数項目入力検査(R1,R2,異常終了).

それを表示する([]).
それを表示する([_氏名,_数学成績,_国語成績|R]) :-
        writef('氏名 : %t\n  数学成績: %t\n  国語成績: %t\n',[[_氏名,_数学成績,_国語成績]),
        それを表示する(R).
        
項目ならび(_項目ならび) :-
行入力(_行),
split(_行,[' '],_文字列ならび),
項目ならび(_文字列ならび,_項目ならび).

行入力(_行) :-
read_line_to_codes(current_input,Codes),
atom_codes(_行,Codes).

split(_文字列,_区切り文字ならび,[_前文字列|R]) :-
副文字列(_文字列,_前文字列,_区切り文字,_後文字列),
member(_区切り文字,_区切り文字ならび),
split(_後文字列,_区切り文字ならび,R),!.
split(_文字列,_,[_文字列]).

副文字列(_文字列,_前文字列,_副文字列,_後文字列) :-
atom_concat(_前文字列,_残り文字列,_文字列),
atom_concat(_副文字列,_後文字列,_残り文字列).

項目ならび(_文字列ならび,_項目ならび) :-
findall(_項目,(
member(_文字列,_文字列ならび),
数値に変換可能なものは変換する(_文字列,_項目)),_項目ならび).

数値に変換可能なものは変換する(_文字列,_項目) :-
atom_number(_文字列,_項目),!.
数値に変換可能なものは変換する(_文字列,_文字列).