下の問題に取り組んでいるのですが、計算結果が明らかにおかしな数になっています。おかしいところとその改善法を教えてください。
よろしくお願いします。
問題:レポートの得点が記録されたプログラムがある。これからデータを読み取り、平均、標準偏差、最大値、最小値を求めるプログラムを求めなさい。
#include <stdio.h>
int main (int argc, const char * argv[/url]) {
int max,min,i;
double average,stdev;
char line[100],name[100],point[100];
int sum=0;
double diff[100];
double a[100];
FILE*in_file;
in_file=fopen("/auto_mnt/home1/09nen/1EC09098K/Documents/File1.txt","r");
if(in_file==NULL){
return 0;
}
while(fgets(line,100,in_file)!=NULL) {
sscanf(line, "%" "%s" ,name,point);
}
for (i=0;i<100;i++)
{
sum+=point;
}
average=sum/name;
for (i=0;i<100;i++)
{
diff=average-point;
}
for (i=0;i<100;i++)
{
a=pow(diff,2);
}
for (i=0;i<100;i++)
{
sum+=a;
}
stdev=sqrt(sum/name);
for (i=0;i<100;i++)
{
if(max<point) max=point;
if(min>point[i]) min=point[i];
}
printf("平均=%f, 標準偏差=%f,最大値=%d,最小値=%d\n",average,stdev,max,min);
fclose(in_file);
return 0;
}
ファイルを読み込んで計算
-
パコネコ
Re:ファイルを読み込んで計算
勘違いならごめんなさい。
そして勉強のために教えてください。
>sscanf(line, "%" "%s" ,name,point);
ここにある"%"ってなんですか?
位置的にはnameと連動しているんですよね。
sscanfは使ったことがないんでわかりませんが、%sとか%cなどは知ってるんですが…あとは%d,%fですね。
そして勉強のために教えてください。
>sscanf(line, "%" "%s" ,name,point);
ここにある"%"ってなんですか?
位置的にはnameと連動しているんですよね。
sscanfは使ったことがないんでわかりませんが、%sとか%cなどは知ってるんですが…あとは%d,%fですね。
-
ドラ
Re:ファイルを読み込んで計算
とりあえずコメントを入れてみました。
#include <stdio.h>
int main (int argc, const char * argv[/url]) { // コマンドライン引数を使ってないのでvoidでいいのでは?
int max,min,i;
double average,stdev;
char line[100],name[100],point[100]; // nameはchar型の2次元配列、pointはint型の配列では?
// またline配列の100とpoint配列の100は同じ100でも意味が違います。
// マジックナンバーを使わずマクロにでも置き換えてください。
int sum=0;
double diff[100];
double a[100];
FILE*in_file;
// 質問するときはファイルのデータも載せた方がいいです。実行できない。
// 回答者の側でファイルを用意すればできるけど、めんどくさ過ぎる。
// ついでに、そのファイルを正しく処理できたときの計算結果も載せるとGood!
in_file=fopen("/auto_mnt/home1/09nen/1EC09098K/Documents/File1.txt","r");
if(in_file==NULL){
return 0;
}
while(fgets(line,100,in_file)!=NULL) {
sscanf(line, "%" "%s" ,name,point); // "%" "%s" は "%%s"と同じですが・・・
}
for (i=0;i<100;i++) // ファイル内のデータは100件に決め打ちしていいのですか?
{
sum+=point; // 現状では文字コードを合計する事になってしまいます。
}
average=sum/name; // 平均を計算するときの分母は人数(データの件数)ですよ。
for (i=0;i<100;i++)
{
diff=average-point;
}
for (i=0;i<100;i++)
{
a=pow(diff,2); // pow()を使うときは #include <math.h> が必要。
}
for (i=0;i<100;i++)
{
sum+=a; // sumには平均を計算した時の値が残ったままになっていますが・・・
// また、aはdouble型でsumはint型。小数点以下が切り捨てられてしまいます。
}
stdev=sqrt(sum/name ); // 分母は人数(データの件数)ですよ。
for (i=0;i<100;i++)
{
if(max<point) max=point[i]; // 未初期化のmax(ゴミ値)をいきなり使用しています。
if(min>point[i]) min=point[i]; // 未初期化のmin(ゴミ値)をいきなり使用しています。
}
printf("平均=%f, 標準偏差=%f,最大値=%d,最小値=%d\n",average,stdev,max,min);
fclose(in_file);
return 0;
}-
toyo
Re:ファイルを読み込んで計算
「レポートの得点が記録されたプログラムがある。」
問題はこの通りでしょうか
普通は記録されたファイルでプログラムというのは変ですね
データを読み取るにはそのデータのフォーマットがわからないとどうしようもないです
テキスト形式で名前と得点がコンマ区切りで1データ毎に改行されているとか
問題はこの通りでしょうか
普通は記録されたファイルでプログラムというのは変ですね
データを読み取るにはそのデータのフォーマットがわからないとどうしようもないです
テキスト形式で名前と得点がコンマ区切りで1データ毎に改行されているとか
-
パコネコ
Re:ファイルを読み込んで計算
>sscanf(line, "%" "%s" ,name,point); // "%" "%s" は "%%s"と同じですが・・・
すいません、%%sも知らないのですが…教えていただけないでしょうか?
む、ということは数が合わないからやっぱり別?
ファイルからの読み込みのときに私は一マスあけてます。
でも開けなくてもできましたっけ?
結局「%」って何なんですか~…ミス?
すいません、%%sも知らないのですが…教えていただけないでしょうか?
む、ということは数が合わないからやっぱり別?
ファイルからの読み込みのときに私は一マスあけてます。
でも開けなくてもできましたっけ?
結局「%」って何なんですか~…ミス?
-
ドラ
Re:ファイルを読み込んで計算
>パコネコさん
"%" "%s" が "%%s"と同じになるのは空白類文字を挟んで隣接する文字列リテラル同士は
コンパイル時に連結されて1つの文字列リテラルになるからです。
scanf系関数の書式指定文字列の中で%は変換指定を書くときの特別な文字なので
"%%"と2つ続けることで'%'という1文字を表します。
scanf系の書式指定文字列中に出てくる変換指定以外の文字には次のような意味があります。
・'%'という文字を読み捨てろ。読み込み不一致ならsscanf終了。
・次に's'という文字を読み捨てろ。読み込み不一致ならsscanf終了。
・おしまい。
結局、変数に何も読み込めていないのです。
ルーニーさんが書き間違っただけだと思いますよ。
"%" "%s" が "%%s"と同じになるのは空白類文字を挟んで隣接する文字列リテラル同士は
コンパイル時に連結されて1つの文字列リテラルになるからです。
scanf系関数の書式指定文字列の中で%は変換指定を書くときの特別な文字なので
"%%"と2つ続けることで'%'という1文字を表します。
scanf系の書式指定文字列中に出てくる変換指定以外の文字には次のような意味があります。
空白類文字・・・空白類文字が続く限り読み捨てろ。
それ以外・・・・その文字を読み捨てろ。読み込み不一致を起こしたら、
その文字をストリームに残したままscanf系関数を終了。
つまり"%%s"では、次のような意味になります。・'%'という文字を読み捨てろ。読み込み不一致ならsscanf終了。
・次に's'という文字を読み捨てろ。読み込み不一致ならsscanf終了。
・おしまい。
結局、変数に何も読み込めていないのです。
ルーニーさんが書き間違っただけだと思いますよ。