プロが教える店舗&オフィスのセキュリティ対策術

c言語についての質問です。あるdatファイルに振幅と時間のデータが保存されています。
このdatファイルを読み込み振幅の最大値を求めてから振幅の2割の値を求めます。
そこから再度読み込み振幅の2割を超える時間まで読み込み越えた際の時間を出力したいのですが上手くいきません。途中がけのプログラムをのせるのでお願いします。
datファイルには
時間 振幅
時間 振幅

のようになっています。

#include <stdio.h>
#include <math.h>
int main(void) {
const char * fname = "C1rbc1(50,0)sq,almi00001.dat";
char line[BUFSIZ];
double amp, time,arrival, max=0,max20;
FILE *fp = fopen(fname, "r");
while (fgets(line, BUFSIZ, fp)) {
sscanf(line, "%lf%lf", &time, &amp);
if (amp > max) {
max = amp;
max20=max*0.2;
}
}
fclose(fp);
printf("max: %.7lf\n", max);
printf("0,2*max:%.7lf\n",max20);

int main(void) {
FILE *fp =fopen(fname,"r");
while (fgets(line, BUFSIZ, fp)){
sscanf(line,"%lf%lf",&time,&amp);
if(amp>max20){
arrival=time;
break;
}
}
fclose(fp);
printf("arrival:%.7lf\n",arrival);

return 0;
}
}

A 回答 (4件)

こんな感じ。



確認はしていません。
質問にあるプログラムと、ほとんど同じ(max20 は毎回確認せずに、max * 0.2 で計算していますが)なので、よく確認してください。

おそらく、いくつかの「例題」をそのまま引っ張ってきて、一本にしたのでしょう。
たとえば、

FILE *fp = fopen(fname, "r");

という、「決り文句」が2回(ファイルを2回スキャンする必要があるので)出てきますが、同じ関数の中で、これを二つ書くことはできません。(実は、書く方法もあります)

そこで、二番目の
FILE *fp = fopen(fname, "r");

のまえに、いつも書いている main() を持ってきたというのは何となくわかります。
エラーが出たときに、「なぜエラーなのか?」を理解せずに「とにかくエラーを消す」という方針で進むと、いずれ困ったことになります。

あと、プログラムの動作を記述する言葉の使い方にも慣れましょう。

> 振幅の2割を超える時間まで読み込み越えた際の時間を

 振幅の最大値の2割を、始めて超えたときの時間 ですね。

-------------- form here ------------------------

#include <stdio.h>
int main(void)
{
const char * fname = "C1rbc1(50,0)sq,almi00001.dat";
char line[BUFSIZ];
double amp, time,arrival, max=0;
FILE *fp = fopen(fname, "r");
while (fgets(line, BUFSIZ, fp)) {
sscanf(line, "%lf%lf", &time, &amp);
if (amp > max) {
max = amp;
}
}
fclose(fp);
printf("max: %.7lf\n", max);

fp=fopen(fname,"r");
while (fgets(line, BUFSIZ, fp)){
sscanf(line,"%lf%lf",&time,&amp);
if(amp > max * 0.2){
arrival=time;
break;
}
}
fclose(fp);
printf("arrival:%.7lf\n",arrival);
return 0;
}
    • good
    • 0

mainの中にmainがまたあったりしてよくわかりませんが、上手くいかないというのはどのようにうまくいかないのでしょうか。

そこら辺がわからないと何とも言えませんけど。

1点気になったのは、値をdoubleで扱っている点です。
例えば、テキストデータが以下のようになっているとします。

時刻 振幅
1.0 2.0
1.1 2.1
1.2 10.5

振幅の最大は10.5です。ですから0.2を乗ずると2.1になりmax20には2.1が入ります。
そこで再度頭から比較していくと、時刻1.1の時にampとmax20が一致するはずです。

でも実際には一致しません。
それは0.2という値に原因があります。0.2を2進数で表現すると0.00110011001100110011…と無限に続きます。当然doubleという入れ物の長さは有限なので切り捨てることになります。そんな訳で、0.2とコーディングしても実際には(正確ではありませんが)1.9999998みたいな若干小さな値になってしまいます。そんな訳で一致するはずだけど一致しないといった問題が発生するかもしれません。
    • good
    • 0

なんでmainが2つあるの?

    • good
    • 0

あなたのコードは関数定義以外を除くとこうなっています。

本当にこれでいいのかよく考えましょう。

int main(void) {

int main(void) {
}
}
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!