気象庁のデータベースからテキストコピペしたテキストファイルを自分で作成し,そこから必要な数字だけ抜き出したいのですが,コンパイルすると
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++;
}
}
}
ネットや教科書を参照してずっと考えたり試行錯誤しておりますが,うまくいきませんでした.
数年分のデータを計算したいのでプログラムを作る事となり,どうしても必要です
力を貸してもらえないでしょうか.
よろしくお願いいたします.
太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
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タグで囲うようにして下さい。
囲わないと,インデントが崩れて読みにくくなります。
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タグで囲うようにして下さい。
囲わないと,インデントが崩れて読みにくくなります。
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
1 まず、気象庁のHPからコピーします。(CTRL-C)
2 EXCELを立ち上げます。
3 a1セルをクリックして、貼り付け(CTRL-V)します。
4 あとは、好きに加工してください。
どうしても、Cで行いたいですか?
2 EXCELを立ち上げます。
3 a1セルをクリックして、貼り付け(CTRL-V)します。
4 あとは、好きに加工してください。
どうしても、Cで行いたいですか?
non
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
明らかにC言語でやるような処理じゃないですよね。
文字列処理が一番苦手な言語のひとつでしょうし。
文字列処理が一番苦手な言語のひとつでしょうし。
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
YuOさん
ご教示くださりありがとうございます。
早速その通りに修正したいのですが、土日は1日中アルバイトとレポートで時間がないので月曜日に修正し、ご報告致します。
講義でC言語を勉強したので活用したかったためエクセルではなくプログラミングをしたいと考えました。
時間も限られていて後にも引けないのが現状です。
ここまで文字列処理が必要になると思わなかったのですが、結局必要になってしまいました。
見通しを立てるのが甘かったと思っています。
しかし、出来ないこともないと思います。
ご返信くださった皆さまありがとうございます。
月曜日にまた来ます
ご教示くださりありがとうございます。
早速その通りに修正したいのですが、土日は1日中アルバイトとレポートで時間がないので月曜日に修正し、ご報告致します。
講義でC言語を勉強したので活用したかったためエクセルではなくプログラミングをしたいと考えました。
時間も限られていて後にも引けないのが現状です。
ここまで文字列処理が必要になると思わなかったのですが、結局必要になってしまいました。
見通しを立てるのが甘かったと思っています。
しかし、出来ないこともないと思います。
ご返信くださった皆さまありがとうございます。
月曜日にまた来ます
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
目的がC言語の勉強なら、がんばってください。某高専生 さんが書きました: 講義でC言語を勉強したので活用したかったためエクセルではなくプログラミングをしたいと考えました。
時間も限られていて後にも引けないのが現状です。
ただ、「後にも引けない」ってのは意味がわからない。
non
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
こちらのちょっとした諸事情です.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);
これはどこがおかしいのか調べるためにおいただけで実際にプログラムを回す際には削除します
調べた結果 この部分がおかしいと思っています.
これからまたバイトなので中断して明日の午後からまたやります.
何度も申し訳ないのですが,ご教示お願いいたします.
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
とりあえず、変数の名前の付け方が悪いので、バグも出やすいというものです。もっと分かりやすい変数名をつけて下さい。
それから、きちんとインデントを揃えて下さい。 こういう書き方は 罠 以外の何者でもありません。
インデントのやり方が分からないなら投稿前チェックリストの「チェック3 : インデントを揃えよう」を御覧ください。
さて、パッと見ですが ここはおかしいですね。while文の中でfpが変更されることはありませんから、while文が実行されるときにfp != NULLならば、このwhileは無限ループになります。
他の部分は変数名が分かりにくすぎるので読んでおりません。
- ループカウンタ用としてi, j, k
- 文字配列としてs
それから、きちんとインデントを揃えて下さい。 こういう書き方は 罠 以外の何者でもありません。
インデントのやり方が分からないなら投稿前チェックリストの「チェック3 : インデントを揃えよう」を御覧ください。
さて、パッと見ですが ここはおかしいですね。while文の中でfpが変更されることはありませんから、while文が実行されるときにfp != NULLならば、このwhileは無限ループになります。
他の部分は変数名が分かりにくすぎるので読んでおりません。
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
なんかよく分からないくらい複雑なことをしていますが、5つ目と8つ目だけを読み込んであとは無視したらいいのでfscanfで十分かと思います。
これでどうでしょう?
beatleさんも仰ってますがインデントをしっかりとつけてください。
また、インデントスタイルは一つに統一した方が良いかと思います。(今はK&RスタイルとGNUスタイルが混在しています。)
それからstrtokは最初は分解対象文字列の先頭アドレスを渡しておいて、その分解の二回目以降の呼び出しにはNULLを指定します。
http://www9.plala.or.jp/sgwr-t/lib/strtok.html
#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: 太陽光発電量の計算をするプログラムを作成中ですが,行き詰まりました
beatleさん
変数やインデントについてあまりにも酷い状態ですね.修正します.
ポインタについて理解不足であることを痛感しました.
ご指摘ありがとうございます.
bitter_foxさん
勉強になります.
貼って下さったコードの内容は完全には理解できておりません.
文字列処理の箇所はほとんど独学でやっていてまだまだ勉強不足です.
また調べてしっかり理解していきたいと思います.
ご教示くださりありがとうございます.
そうですね.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
勉強になります.
貼って下さったコードの内容は完全には理解できておりません.
文字列処理の箇所はほとんど独学でやっていてまだまだ勉強不足です.
また調べてしっかり理解していきたいと思います.
ご教示くださりありがとうございます.