個数のわからないものの平均値

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
べけん
記事: 21
登録日時: 5年前

個数のわからないものの平均値

#1

投稿記事 by べけん » 5年前

データの数がわからないものの平均をとるというプログラムを組もうとしました。
一つ目だと564個のときしか測れないプログラムですがこれをさらに拡張して二つ目のように数がいくつのときでも平均を出せるようなプログラムにしたつもりですが平均値が全てnanになってしまいます。
どなたか解決方法を教えていただきたいです。

コード:


#include<stdio.h>
double average(double *a,int n)
{
	int i;
	double sum=0;
	double heikin;
	
	for(i=0;i<n;i++){
		sum=sum+a[i];
	}
	
	heikin=sum/n;

	return heikin;
}

void main()
{
	int i,j,k,n=564; /*  テストは n=2  本番では  n=564  */
	double a[564];	/*配列を定義する*/
	FILE *fp_in;	/*0:ファイルポインタの宣言(ファイルを扱う場合には,この宣言は必ず必要!)*/
	FILE *fp_out;
	char filepath[256];

	fp_out=fopen("aa1.txt","w");

double Hei_kin;

	if(fp_out==NULL){
		printf("ファイルがありません\n");
		return;
	}
	
	
	for(j = 1; j <= 26; j++){
		sprintf(filepath,"a%d.txt",j);

	
		
	fp_in=fopen(filepath,"r");	/*1:ファイルを読み込み専用で開く*/

	if(fp_in==NULL){		/*1:エラーチェック*/
		printf("ファイルがありませんでした.%\n");
		return;	/*1:プログラムの強制終了*/
	}

	
	for(i=0;i<n;i++){							
		fscanf(fp_in,"%le",&a[i]);	/*2:ファイルからデータをスキャンし,配列に格納する.*/
	
	}
		
		k = 10 * j + 40; /* ??? わかんない(^^; */

Hei_kin=average(a,n);

	fprintf(fp_out,"%d %le\n", k, Hei_kin);
	fclose(fp_in);	/*3:ファイルを閉じる(これを忘れると,ファイルが開いたままになる.)*/
	}
	
	fclose(fp_out);
	
	
}

コード:



#include<stdio.h>
double average(double *a,int n)
{
	int i;
	double sum=0;
	double heikin;
	
	for(i=0;i<n;i++){
		sum=sum+a[i];
	}
	
	heikin=sum/n;

	return heikin;
}

void main()
{
	int i,j,k,n=564; /*  テストは n=2  本番では  n=564  */
	double a[564];	/*配列を定義する*/
	FILE *fp_in;	/*0:ファイルポインタの宣言(ファイルを扱う場合には,この宣言は必ず必要!)*/
	FILE *fp_out;
	char filepath[256];

	fp_out=fopen("aa1.txt","w");

double Hei_kin;

	if(fp_out==NULL){
		printf("ファイルがありません\n");
		return;
	}
	
	
	for(j = 1; j <= 26; j++){
		sprintf(filepath,"a%d.txt",j);

	
		
	fp_in=fopen(filepath,"r");	/*1:ファイルを読み込み専用で開く*/

	if(fp_in==NULL){		/*1:エラーチェック*/
		printf("ファイルがありませんでした.%\n");
		return;	/*1:プログラムの強制終了*/
	}

	
	for(i=0;i<n;i++){							
		if(a[i] == '\0'){
			break;
		}
		else{
		fscanf(fp_in,"%le",&a[i]);	/*2:ファイルからデータをスキャンし,配列に格納する.*/
		}
	}
		k = 10 * j + 40; /* ??? わかんない(^^; */

Hei_kin=average(a,n);

	fprintf(fp_out,"%d %le\n", k, Hei_kin);
	fclose(fp_in);	/*3:ファイルを閉じる(これを忘れると,ファイルが開いたままになる.)*/
		
	}
	
	fclose(fp_out);
	
	
}



アバター
usao
記事: 1887
登録日時: 11年前

Re: 個数のわからないものの平均値

#2

投稿記事 by usao » 5年前

平均値の算出結果がおかしいのであれば,
平均値の算出処理か,あるいはその算出処理に与えたデータがおかしいであろうことは容易に推測できますよね.
例えば,後者側を怪しむならば,
average()の引数である,aとnの一方あるいは両方の値の妥当性を確認すべきです.
他人に訊く前に,そういうデバッグ作業をご自身でやってみてはいかがでしょうか?
・average()に渡される時点でのnの値は何になるべきですか? → 実際にそうなっていますか?
・a[]の中身には,本当にファイルの内容が正しく読み込めていますか?

Math

Re: 個数のわからないものの平均値

#3

投稿記事 by Math » 5年前

2個 2ファイル で考えれば十分だよね。

Windows10、CX-Builder 10.3( Borland C [BCC55] 後継 ) 使用

main.c

コード:



#include<stdio.h>
double average(double *a,int n)
{
	int i;
	double sum=0;
	double heikin;
	
	for(i=0;i<n;i++){
		sum=sum+a[i];
	}
	
	heikin=sum/n;

	printf("\n sum=%le n=%d heikin=%le \n",sum,n,heikin); /* calc. check */

	return heikin;
}

void main()
{
	int i,j,k,n; /*  n=任意  前はn=564  */
	double a[564];	/*配列を定義する*/
	FILE *fp_in;	/*0:ファイルポインタの宣言(ファイルを扱う場合には,この宣言は必ず必要!)*/
	FILE *fp_out;
	char filepath[256];

	fp_out=fopen("aa1.txt","w");

double Hei_kin;


	if(fp_out==NULL){
		printf("ファイルがありません\n");
		return;
	}
	
	//-----------------------------------------------------------------------------------------
	// for(j = 1; j <= 26; j++){

	for(j = 1; j <= 2; j++){

		sprintf(filepath,"a%d.txt",j);

printf("*** %s\n",filepath);
	
		
	fp_in=fopen(filepath,"r");	/*1:ファイルを読み込み専用で開く*/

	if(fp_in==NULL){		/*1:エラーチェック*/
		printf("ファイルがありませんでした.%\n");
		return;	/*1:プログラムの強制終了*/
	}

	
	for(i=0;i<1000;i++){							
//		if(a[i] == '\0'){
//			break;
//		}
//		else{
		if(fscanf(fp_in,"%le",&a[i])==EOF)break;	/*2:ファイルからデータをスキャンし,配列に格納する.*/
//		}
	}
	n=i;

		k = 10 * j + 40; /* ??? わかんない(^^; */

Hei_kin=average(a,n);

	fprintf(fp_out,"%d %le\n", k, Hei_kin);
	fclose(fp_in);	/*3:ファイルを閉じる(これを忘れると,ファイルが開いたままになる.)*/
		
	}
	
	fclose(fp_out);
	
	
}

cx.bat

コード:

"C:\Program Files (x86)\Embarcadero\Studio\20.0\bin\bcc32" main.cpp

dir main.exe

main.exe

pause
実行する。
http://www2.koyoen.birdview.co.jp/~abcx ... -15-x-.PNG

かずま

Re: 個数のわからないものの平均値

#4

投稿記事 by かずま » 5年前

Math さんが書きました:
5年前

コード:

	double a[564];	/*配列を定義する*/
	
	for(i=0;i<1000;i++){
							
		if(fscanf(fp_in,"%le",&a[i])==EOF)break;	/*2:ファイルからデータをスキャンし,配列に格納する.*/
546個分しか領域がないのに、データを1000個読み込まようとするとは、
プログラムのセンスが疑われます。double a[1000]; にしたとしても、
個数の分からないデータは読み込めないことがあります。

次のプログラムは、個数の分からないデータの平均値を求める一例です。
これを参考に、質問者がプログラムを完成させて貼り付けてくれることを
希望します。

コード:

#include <stdio.h>

int main(void)
{
	FILE *fp = fopen("a1.txt", "r");
	if (fp == NULL) { puts("can't open a1.txt\n"); return 1; }

	double x, sum = 0;
	int n = 0;
	while (fscanf(fp, "%lf", &x) == 1) {
		printf(" %g", x);
		sum += x;
		n++;
	}
	fclose(fp);
	printf("\nn = %d, sum = %g, average = %g\n", n, sum, sum / n);
}
a1.txt

コード:

 31.4 15.9
26.5 35.8 97.9 
実行結果

コード:

 31.4 15.9 26.5 35.8 97.9
n = 5, sum = 207.5, average = 41.5
これでも int が 32ビットだとして、2147483648個以上のデータについて
は正しい結果が出ませんが、そこまでは要求されないでしょう。

Math

Re: 個数のわからないものの平均値

#5

投稿記事 by Math » 5年前

[訂正]
a[564] 関連は適宜合理的な値に変更すること(^^;
そのくらいわかるよね。

コード:



#include<stdio.h>
double average(double *a,int n)
{
	int i;
	double sum=0;
	double heikin;
	
	for(i=0;i<n;i++){
		sum=sum+a[i];
	}
	
	heikin=sum/n;

	printf("\n sum=%le n=%d heikin=%le \n",sum,n,heikin); /* calc. check */

	return heikin;
}

void main()
{
	int i,j,k,n; /*  n=任意  前はn=564  */
	double a[564];	/*配列を定義する*/
	FILE *fp_in;	/*0:ファイルポインタの宣言(ファイルを扱う場合には,この宣言は必ず必要!)*/
	FILE *fp_out;
	char filepath[256];

	fp_out=fopen("aa1.txt","w");

double Hei_kin;


	if(fp_out==NULL){
		printf("ファイルがありません\n");
		return;
	}
	
	//-----------------------------------------------------------------------------------------
	// for(j = 1; j <= 26; j++){

	for(j = 1; j <= 2; j++){

		sprintf(filepath,"a%d.txt",j);

printf("*** %s\n",filepath);
	
		
	fp_in=fopen(filepath,"r");	/*1:ファイルを読み込み専用で開く*/

	if(fp_in==NULL){		/*1:エラーチェック*/
		printf("ファイルがありませんでした.%\n");
		return;	/*1:プログラムの強制終了*/
	}

	
	for(i=0;i<564;i++){							
//		if(a[i] == '\0'){
//			break;
//		}
//		else{
		if(fscanf(fp_in,"%le",&a[i])==EOF)break;	/*2:ファイルからデータをスキャンし,配列に格納する.*/
//		}
	}
	n=i;

		k = 10 * j + 40; /* ??? わかんない(^^; */

Hei_kin=average(a,n);

	fprintf(fp_out,"%d %le\n", k, Hei_kin);
	fclose(fp_in);	/*3:ファイルを閉じる(これを忘れると,ファイルが開いたままになる.)*/
		
	}
	
	fclose(fp_out);
	
	
}

Math

Re: 個数のわからないものの平均値

#6

投稿記事 by Math » 5年前

viewtopic.php?f=3&t=20576

続きとして考えかたを説明したのだけど ”わからない” とかいておいたところは何なのか説明してね。

shika
記事: 6
登録日時: 5年前

Re: 個数のわからないものの平均値

#7

投稿記事 by shika » 5年前

一番最初のプログラムでは、filepathが入力されていません。

shika
記事: 6
登録日時: 5年前

Re: 個数のわからないものの平均値

#8

投稿記事 by shika » 5年前

一番最初のプログラムでは、filepathが入力されていません。by shika

shika
記事: 6
登録日時: 5年前

Re: 個数のわからないものの平均値

#9

投稿記事 by shika » 5年前

すいません。使い方が良く分からず慣れていないので、同じ返信を繰り返し送信してしまいました。
全く申し訳ありません。by shika

shika
記事: 6
登録日時: 5年前

Re: 個数のわからないものの平均値

#10

投稿記事 by shika » 5年前

ファイルの中にファイルを展開する方法など全く私には分かりませんが、別にそんな複雑な方法を取らなくても、私なりに出来ました。外部ファイルへの書き込みで算出するなら、入力個数を数えながら、書き込みし。その個数にもとずいて読込んで、合計を計算しつつ最後に平均すれば、出来ます。わざわざ配列を使う必要はありません。全合計を入力個数で割ればいいのですから。by shika

返信

“C言語何でも質問掲示板” へ戻る