太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
某高専生

太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#1

投稿記事 by 某高専生 » 12年前

気象庁のデータベースからテキストコピペしたテキストファイルを自分で作成し,そこから必要な数字だけ抜き出したいのですが,コンパイルすると

1b.c:46: 警告: 互換性のないポインタ型からの引数 1 個の `strtok' を渡しますです
1b.c:49: 警告: 引数 1 個の `atof' を渡しますにより、キャストなしで整数からポインタを作りました
1b.c:50: 警告: 引数 1 個の `atof' を渡しますにより、キャストなしで整数からポインタを作りました

と出て,うまくいきません


http://www.data.jma.go.jp/obd/stats/etr ... urly&view=


1 997.6 1007.1 0.0 24.3 21.0 24.9 82 1.5 南
2 997.2 1006.7 1.5 23.6 21.1 25.1 86 3.1 南西
3 996.4 1005.9 1.0 23.1 21.0 24.9 88 0.2 静穏 10 10.0
4 996.3 1005.8 0.5 23.5 21.2 25.2 87 1.1 北西
5 996.8 1006.3 0.0 22.6 20.5 24.1 88 2.2 西 0.0 0.00
6 997.1 1006.6 0.5 22.5 20.8 24.5 90 3.7 西 0.0 0.01 10 4.00
7 997.2 1006.7 3.5 22.5 20.6 24.3 89 3.8 西 0.0 0.12
8 997.8 1007.3 3.5 22.7 20.8 24.6 89 2.6 西南西 0.0 0.15
9 997.0 1006.5 2.5 22.7 20.6 24.3 88 1.6 南西 0.0 0.19 -- -- 10 8.00
10 997.1 1006.6 0.5 23.3 20.5 24.0 84 1.7 西北西 0.0 0.50
11 997.4 1006.9 1.0 23.0 20.0 23.3 83 1.8 西北西 0.0 0.68
12 997.3 1006.8 0.0 24.0 19.3 22.4 75 0.6 北東 0.0 1.02 10 - 10.0
13 997.6 1007.0 -- 24.9 19.1 22.0 70 0.5 北北東 0.0 1.22
14 997.4 1006.8 -- 25.1 19.0 22.0 69 0.3 東 0.0 0.60
15 997.6 1007.0 0.0 25.4 19.5 22.7 70 2.1 西南西 0.0 0.56 -- -- 10 10.0
16 997.5 1007.0 1.0 24.1 20.4 24.0 80 1.8 西 0.0 0.26
17 997.3 1006.8 0.0 24.2 20.5 24.2 80 1.1 西 0.0 0.30
18 997.7 1007.2 -- 24.5 20.2 23.7 77 2.5 西 0.0 0.22 10 8.00
19 998.1 1007.6 -- 24.0 20.5 24.2 81 1.6 北 0.0 0.07
20 998.7 1008.2 -- 23.8 18.2 20.9 71 1.9 北 0.0 0.00
21 999.3 1008.8 -- 23.4 17.6 20.2 70 2.2 北北東 -- -- 10 - 8.00
22 1000.1 1009.6 -- 22.9 17.4 19.8 71 2.1 北北東
23 1000.0 1009.5 -- 22.7 17.2 19.6 71 1.3 北北東
24 1000.1 1009.7 -- 22.2 16.9 19.3 72 2.1 北東

これの左から5個目の数列と8個目の数列(1番上なら”24.3”と”82”)だけを抜き出して式に使いたいのです.

作ったプログラムは以下のとおりです
c言語初心者で雑なところがありますがご容赦ください


/* 1b.c */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define pi 3.14159265358979
void main()
{
int i,j,k,kk,ii,l=1;
double a[366],b[366],c[366],d[366],e1,e2,f,g,h,v,w,x,y,z,Q,S=1366.;
char str,s1[15],s2[60],o[61],u[10],r[15],q[15],s[16][60];
FILE *fp;
char *tp;
fp = fopen("text1.txt","r"); /このテキストファイルは,先ほどのテキストファイルとは無関係です/
if (fp == NULL)
return;
i=0;
j=0;
k=0;
while(1)
{
fgets(s1,15,fp);
strncpy(r,s1+0,4);
strncpy(q,s1+5,15);
e1 =atof(r);
e2 =(double *)e1*pi/180;
printf("%s %f %f\n\n",q,e1,e2);

if(feof(fp))
break;
j++;
}
fclose(fp);

fp = fopen("text2.txt","r");
if (fp == NULL)
return;
for(k=172;k<=172;k++){
f=23.44*cos((172.-k)*pi/180.);

while(2) /*問題の箇所がここの部分です*/
{

fgets(o,60,fp);
for(kk=0;kk<=16;kk++){
while(fp != NULL){
tp=strtok(fp," \n");         /*46行目*/
}}

a =atof(*s[5]);            /*49行目*/
b =atof(*s[8]);            /*50行目*/
printf("%f %f\n",a,b);

h=(12.-l)*15.;
g=6.11*pow(10.,((7.5*a)/(237.3+a)))*b/100.;
v=sin(e2)*sin(f*pi/180.)+cos(e2)*cos(f*pi/180.)*cos(h*pi/180.);
w=v*180./pi;
Q=S*pow(sin(v),2.)/((sin(v)+2.7)*pow(10.,-3.)*g+1.085*sin(v)+0.1);
if(Q<0){
Q=0;
}
printf("%f\n",Q);

if(feof(fp))
break;
i++;
l++;
}
}
}


ネットや教科書を参照してずっと考えたり試行錯誤しておりますが,うまくいきませんでした.

数年分のデータを計算したいのでプログラムを作る事となり,どうしても必要です

力を貸してもらえないでしょうか.
よろしくお願いいたします.

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#2

投稿記事 by YuO » 12年前

strtokは,char *とconst char *を引数にとります。
FILE *であるfpを渡しても,正常に動作しません。
fgetsなどでファイルから一行読み込んで,読んだ文字列をstrtokの第一引数に渡すようにすれば,最初の警告は対処できます。

次に,atofはconst char *を引数にとります。
今回,sはchar [16][60]型ですから,*s[5]のように,二回参照外しをすればchar型になってしまいます。
本来,s[5]などのように,*が付かないのが意に沿った書き方なのではないでしょうか。
# s[5]の配列へ値が代入されていないため,予想ですが。
ついでに,strtokしたタイミングで,s[0]等に文字列をstrcpyしておきましょう。
# たぶん,これをしていないのも問題。
あと,配列は0から数えます。s[0]を使わないのであれば良いですが,5番目の要素はおそらくs[4]に入っています。


最後に,フォーラムルールに従って,コードを貼り付ける場合はcodeタグで囲うようにして下さい。
囲わないと,インデントが崩れて読みにくくなります。

non
記事: 1097
登録日時: 13年前

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#3

投稿記事 by non » 12年前

1 まず、気象庁のHPからコピーします。(CTRL-C)
2 EXCELを立ち上げます。
3 a1セルをクリックして、貼り付け(CTRL-V)します。
4 あとは、好きに加工してください。

どうしても、Cで行いたいですか?
non

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#4

投稿記事 by h2so5 » 12年前

明らかにC言語でやるような処理じゃないですよね。
文字列処理が一番苦手な言語のひとつでしょうし。

某高専生

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#5

投稿記事 by 某高専生 » 12年前

YuOさん

ご教示くださりありがとうございます。
早速その通りに修正したいのですが、土日は1日中アルバイトとレポートで時間がないので月曜日に修正し、ご報告致します。


講義でC言語を勉強したので活用したかったためエクセルではなくプログラミングをしたいと考えました。
時間も限られていて後にも引けないのが現状です。


ここまで文字列処理が必要になると思わなかったのですが、結局必要になってしまいました。
見通しを立てるのが甘かったと思っています。

しかし、出来ないこともないと思います。


ご返信くださった皆さまありがとうございます。
月曜日にまた来ます

non
記事: 1097
登録日時: 13年前

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#6

投稿記事 by non » 12年前

某高専生 さんが書きました: 講義でC言語を勉強したので活用したかったためエクセルではなくプログラミングをしたいと考えました。
時間も限られていて後にも引けないのが現状です。
目的がC言語の勉強なら、がんばってください。
ただ、「後にも引けない」ってのは意味がわからない。
non

某高専生

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#7

投稿記事 by 某高専生 » 12年前

non さんが書きました: 目的がC言語の勉強なら、がんばってください。
ただ、「後にも引けない」ってのは意味がわからない。
こちらのちょっとした諸事情です.
特に意味はありませんのであまり気になさらないでくださいw


今日の講義が終わってからご指摘を受けて考え,修正してみて,警告はなくなりましたがうまくいきません.

以下現在のプログラムコードを貼ります.
以前コードを貼る際にcodeタグで囲っていなかったことについてお詫びいたします.

コード:

/* 1b.c */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define pi 3.14159265358979
main()
{
  int i,j,k,kk,ii,l=1;
  double a[366],b[366],c[366],d[366],e1,e2,f,g,h,v,w,x,y,z,Q,S=1366.;
  char str,s1[15],s2[61],*s3,o[61],u[10],r[15],q[15],s[16][60];
  FILE *fp;
  char *tp;
  fp = fopen("text1.txt","r");
  if (fp == NULL)
    return;
  i=0;
  j=0;
  k=0;
  while(1) /*ここはうまく動いているので質問内容とは無関係です*/
    {
      fgets(s1,15,fp);
      strncpy(r,s1+0,4);
      strncpy(q,s1+5,15);
      e1 =atof(r);
      e2 =e1*pi/180;
      printf("%s   %f  %f\n\n",q,e1,e2);

      if(feof(fp))
        break;
      j++;
    }
  fclose(fp);

  fp = fopen("100623.txt","r"); /*問題の箇所はここからです*/
  if (fp == NULL)
    return;
  for(k=172;k<=172;k++){
    f=23.44*cos((172.-k)*pi/180.);
  while(2)
    {

      fgets(o,60,fp);
      printf("%s\n",o);
      while(fp != NULL){
        s3=strtok(o," ");
        for(kk=0;kk<=16;kk++){
          strcpy(s[kk],s3);
        }}
      a[i] =atof(s[4]);
      b[i] =atof(s[7]);
      printf("%f %f\n",a,b);

      h=(12.-l)*15.;
      g=6.11*pow(10.,((7.5*a[i])/(237.3+a[i])))*b[i]/100.;
      v=sin(e2)*sin(f*pi/180.)+cos(e2)*cos(f*pi/180.)*cos(h*pi/180.);
      w=v*180./pi;
      Q=S*pow(sin(v),2.)/((sin(v)+2.7)*pow(10.,-3.)*g+1.085*sin(v)+0.1);
      if(Q<0){
        Q=0;
      }
      printf("%f\n",Q);

      if(feof(fp))
        break;
      i++;
      l++;
    }
  }
}
 
これについて実行したところ

1 997.6 1007.1 0.0 24.3 21.0 24.9 82 1.5

とだけ出力されました.

コード:

 
while(2)
    {

      fgets(o,60,fp);
      printf("%s\n",o);
      while(fp != NULL){
        s3=strtok(o," ");
        for(kk=0;kk<=16;kk++){
          strcpy(s[kk],s3);
        }}

      a[i] =atof(s[4]);
      b[i] =atof(s[7]);
      printf("%f %f\n",a,b);

この部分でまだおかしいところがあると思い,試行錯誤しております.

printf("%s\n",o);
これはどこがおかしいのか調べるためにおいただけで実際にプログラムを回す際には削除します

調べた結果

コード:

 while(fp != NULL){
        s3=strtok(o," ");
        for(kk=0;kk<=16;kk++){
          strcpy(s[kk],s3);
この部分がおかしいと思っています.

これからまたバイトなので中断して明日の午後からまたやります.


何度も申し訳ないのですが,ご教示お願いいたします.

beatle
記事: 1281
登録日時: 12年前
住所: 埼玉
連絡を取る:

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#8

投稿記事 by beatle » 12年前

とりあえず、変数の名前の付け方が悪いので、バグも出やすいというものです。もっと分かりやすい変数名をつけて下さい。
  • ループカウンタ用としてi, j, k
  • 文字配列としてs
くらいは使ってもいいと思いますが、その他の非常に短い変数名(アルファベット1文字とか、アルファベット1文字+数字とか)は使わないようにしたほうが、分かりやすいソースコードになります。

それから、きちんとインデントを揃えて下さい。

コード:

  for(k=172;k<=172;k++){
    f=23.44*cos((172.-k)*pi/180.);
  while(2)
    {
こういう書き方は 罠 以外の何者でもありません。
インデントのやり方が分からないなら投稿前チェックリストの「チェック3 : インデントを揃えよう」を御覧ください。

さて、パッと見ですが

コード:

      while(fp != NULL){
        s3=strtok(o," ");
        for(kk=0;kk<=16;kk++){
          strcpy(s[kk],s3);
        }}
ここはおかしいですね。while文の中でfpが変更されることはありませんから、while文が実行されるときにfp != NULLならば、このwhileは無限ループになります。

他の部分は変数名が分かりにくすぎるので読んでおりません。

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#9

投稿記事 by bitter_fox » 12年前

なんかよく分からないくらい複雑なことをしていますが、5つ目と8つ目だけを読み込んであとは無視したらいいのでfscanfで十分かと思います。

コード:


#include <stdio.h>
#include <stdlib.h>

#define WEATHER_DATA_MAX 100

#define FALSE (0)
#define TRUE (!FALSE)

typedef struct
{
	double temperature;
	int humidity;
} WeatherData;

int ignoreLine(FILE *fp);
int ignoreString(FILE *fp, int times);

int main()
{
	FILE *fp = fopen("text1.txt", "r");
	int i, countWeatherData;
	WeatherData wd[WEATHER_DATA_MAX];

	if (fp == NULL)
	{
		exit(1);
	}

	for (i = 0; i < WEATHER_DATA_MAX; i++)
	{
		if (ignoreString(fp, 4)                          && // 先頭4つ無視(1, 2, 3, 4)
			fscanf(fp, "%lf", &wd[i].temperature) != EOF && // 5つ目      (5)
			ignoreString(fp, 2)                          && // 2つ無視    (6, 7)
			fscanf(fp, "%d", &wd[i].humidity) != EOF)       // 8つ目      (8)
		{
			ignoreLine(fp);
		}
		else
		{
			break;
		}
	}
	countWeatherData= i;

	for (i = 0; i < countWeatherData; i++)
	{
		printf("%f %d\n", wd[i].temperature, wd[i].humidity);
	}

	return 0;
}

int ignoreLine(FILE *fp)
{
	if (fscanf(fp, "%*[^\n]%*c") == EOF)
	{
		return FALSE;
	}
	return TRUE;
}

int ignoreString(FILE *fp, int times)
{
	int i;

	for (i = 0; i < times; i++)
	{
		if (fscanf(fp, "%*s") == EOF)
		{
			return FALSE;
		}
	}
	return TRUE;
}

これでどうでしょう?

beatleさんも仰ってますがインデントをしっかりとつけてください。
また、インデントスタイルは一つに統一した方が良いかと思います。(今はK&RスタイルとGNUスタイルが混在しています。)

それからstrtokは最初は分解対象文字列の先頭アドレスを渡しておいて、その分解の二回目以降の呼び出しにはNULLを指定します。
http://www9.plala.or.jp/sgwr-t/lib/strtok.html

某高専生

Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました

#10

投稿記事 by 某高専生 » 12年前

beatleさん
beatle さんが書きました: とりあえず、変数の名前の付け方が悪いので、バグも出やすいというものです。もっと分かりやすい変数名をつけて下さい。

こういう書き方は 罠 以外の何者でもありません。
インデントのやり方が分からないなら投稿前チェックリストの「チェック3 : インデントを揃えよう」を御覧ください。
そうですね.
変数やインデントについてあまりにも酷い状態ですね.修正します.

beatle さんが書きました: ここはおかしいですね。while文の中でfpが変更されることはありませんから、while文が実行されるときにfp != NULLならば、このwhileは無限ループになります。
初歩的なミスですね・・.
ポインタについて理解不足であることを痛感しました.
ご指摘ありがとうございます.


bitter_foxさん
bitter_fox さんが書きました:なんかよく分からないくらい複雑なことをしていますが、5つ目と8つ目だけを読み込んであとは無視したらいいのでfscanfで十分かと思います。

beatleさんも仰ってますがインデントをしっかりとつけてください。
また、インデントスタイルは一つに統一した方が良いかと思います。(今はK&RスタイルとGNUスタイルが混在しています。)

それからstrtokは最初は分解対象文字列の先頭アドレスを渡しておいて、その分解の二回目以降の呼び出しにはNULLを指定します。
http://www9.plala.or.jp/sgwr-t/lib/strtok.html
なるほど.
勉強になります.
貼って下さったコードの内容は完全には理解できておりません.
文字列処理の箇所はほとんど独学でやっていてまだまだ勉強不足です.

また調べてしっかり理解していきたいと思います.
ご教示くださりありがとうございます.

閉鎖

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