ページ 11

構造体のポインタと構造体型の関数を用いた問題

Posted: 2010年2月10日(水) 19:21
by 大学1年(初心者)
大学で出された課題についての質問です。正しくプログラムが動いてくれません。どこに原因があるのでしょうか。
このプログラムは、ヤンキースの選手の成績データをプログラムに取り組んで、以下のようなことを出力するプログラムです。

・選択した選手のデータを出力する
・安打数の一番多い選手のデータを出力する
・本塁打数の一番多い選手のデータを出力する
・打率の一番高い選手のデータを出力する
・出塁率の一番高い選手のデータを出力する

例えば、選択した選手のデータを出力したい場合は、出力画面で、enumで定義されている1(NAME)を入力し、そのあと、出力したい選手の名前を入力します(Matsuiなど)

【本体のプログラムのソース】
http://codepad.org/tGSltdvV

【インクルードされるbattingstats.h】
http://codepad.org/RuXvoLGI

【取りこむデータの入ったファイルmlbstats_nyy2009.csv】
http://codepad.org/Vv6lYaMq

また、実際にstats[/url]とnumにデータが格納されているかどうかを確認するためにprintfを実行した出力結果がこれです。→「http://codepad.org/SH0tS1Le
numにはしっかりと格納されているのですが、選手データの内容が狂っています(途中までは正しく格納されているのですが。。。)
おそらく、while(1)の中身が間違っていると思うのですが、どのように直せばよいでしょうか? 画像

Re:無題

Posted: 2010年2月10日(水) 19:29
by たかぎ
意味不明です。
質問は何でしょうか?

Re:無題

Posted: 2010年2月10日(水) 22:20
by Justy
>numとstats[/url]の中身を出力すると、numの中身は0

100: if(fgets(line,sizeof line,fp) != NULL) /* fpからline[/url]に文字列を格納し、終了するまで(NULLを返すまで)繰り返す */
101: break;


 この行が怪しい気がしますね。
 fgetsの処理に成功しているなら戻り値は NULLではないので、そのまま breakが呼ばれ
whileループを抜けてしまうような……。

Re:無題

Posted: 2010年2月11日(木) 00:09
by 大学1年(初心者)
Justyさん

確かにそこは明らかにおかしかったです。見落としてました。
ありがとうございます

ひとまず、num(データ数)は間違いなく格納できたのですが、stats[/url]の中身が大荒れです。
どうすればよいでしょうか

Re:無題

Posted: 2010年2月11日(木) 01:14
by Justy
 中身が更新されたようですね。


>stats[/url]の中身が大荒れです
 loadStatsの中“だけ”でもいろいろおかしな箇所があります。

 まず、名前が "Player"だったらスキップするようになっていますが、この段階では
メンバ nameの文字列の終端が無い可能性があり、その場合 strcmpに失敗するので、
これが機能するかどうかは運次第になります。
 大抵の場合うまく機能しないでしょう。

 次に、ssanfのフォーマットですが、&dが紛れ込んでいます。
 この為、途中で解析に失敗します。


 まず、このあたりの処理を見直してみましょう。
 
 そもそも メンバ nameに名前をセットするのになにやらいろいろやっていますが、
これも含めて sscanfで処理してしまえば BatterStats変数の全てのメンバに対する代入は
一行で出来るはずです

 尚、その際 sscanfの戻り値を見て、どこまで読み込めたかどうかは必ず確認して下さい。

Re:無題

Posted: 2010年2月11日(木) 02:16
by box
119: (stats+tmp)->name[j] = NULL;

ポインタであるNULLをchar型に代入すると、
何かよくないことが起きるかもしれません。
コンパイル時に警告が出ているはずです。

NULLと、文字列の終端を示す'\0'とは全く別物であることを、
まずは理解するとよいでしょう。