
前回の質問に回答して頂いた皆さん、ありがとうございました!
読み込んだデータを格納するための構造体配列の個数が足りなかったという、ごく初歩的なミスが原因でした…///
それが解決したばかりで恐縮ですが、新たな問題が発生しました。
風力発電の発電データを1秒ごとに1日分を記録したCSVファイルを読み込み、集計して、集計用の新しいCSVファイルに書き込むプログラムを組もうとしています。以下にソースコードを記載します。
#include<stdio.h>
#include<stdlib.h>
static char filename[100];
static char wfname[100];
char fname2[256];
void str_copy(char[],char[]);//文字列のコピー
void str_cat(char[],char[]);//文字列の連結
struct kaze {
_char jikoku[16];
_double fuusoku;
_double fuuko;
_double denatu;
_double denryoku1;
_double denryoku2;
_double co2;
};
struct kaze data[86450];
int main()
{
_char date2[50];
_char date3[50];
_char month2[10];
_char year2[10];
_char path1[50]="F:\\風力発電\\風車";
_char path2[10]="年";
_char path3[10]="月\\WP";
_char buff[256];
_int month1,month,year,date;
_int kensuu,i,j,uruu;
_FILE *fpin,*fpout;
_printf("集計する年を入力してください。\n");
_scanf("%d",&year);
_printf("集計する月を入力してください。\n");
_scanf("%d",&month);
_if(month==2){
__printf("閏年ですか?(はい -> 1 いいえ -> 2)");
__scanf("%d",&uruu);
_}
_if(month==2){
__if(uruu==1){
___month1=29;
__}
__else{
___month1=28;
__}
_}
_else if(month==4 || month==6 || month==9 || month==11){
__month1=30;
_}
_else{
__month1=31;
_}
_date=year*100+month;
_sprintf(date3,"%d",date);
_str_copy(wfname,date3);
_str_cat(wfname,".csv");
_sprintf(year2,"%d",year);
_sprintf(month2,"%d",month);
_sprintf(fname2,"%s%s%s%s%s%s",path1,year2,path2,month2,path3,wfname);
_if((fpout=fopen(fname2,"w"))==NULL){
__printf("ファイルが作成できません。 --- %s\n",fname2);
__exit(EXIT_FAILURE);
_}
_fprintf(fpout,"日付,平均風速,平均風向,平均電圧,平均発電電力、発電電力量,CO2削減量\n");
_fprintf(fpout,"年/月/日,m/s,°,V,KW,KWh,kg-c\n");
_printf("集計用ファイルを作成しました。 --- %s\n",fname2);
_fclose(fpout);
_date=year*10000+month*100;
_for(j=1;j<=month1;j++){ //このループ
__double fuusoku=0,fuuko=0,denatu=0,denryoku1=0,denryoku2=0,co2=0;
__date++;
__sprintf(date2,"%d",date);
__str_copy(filename,date2);
__str_cat(filename,".csv");
__sprintf(buff,"%s%s%s%s%s%s",path1,year2,path2,month2,path3,filename);
__if((fpin=fopen(buff,"r"))==NULL){
___printf("ファイルが見つかりません。--- %s\n",buff);
___exit(EXIT_FAILURE);
__}
__for(kensuu = 0; fscanf(fpin, "%[^,],%lf,%lf,%lf,%lf,%lf,%lf\n", data[kensuu].jikoku, &data[kensuu].fuusoku,
&data[kensuu].fuuko, &data[kensuu].denatu, &data[kensuu].denryoku1,
&data[kensuu].denryoku2, &data[kensuu].co2) != EOF; kensuu++); //ここで止まる?
__for(i = 12; i < kensuu; i++){
___fuusoku+=data[i].fuusoku;
___fuuko+=data[i].fuuko;
___denatu+=data[i].denatu;
___denryoku1+=data[i].denryoku1;
}
__fuusoku/=86400;
__fuuko/=86400;
__denatu/=86400;
__denryoku1/=86400;
__denryoku2=data[kensuu-1].denryoku2;
__co2=data[kensuu-1].co2;
__fclose(fpin);
__printf("\n%d年%d月%d日の集計結果\n平均風速:%lf(m/s)\n平均風向:%lf(°)\n
__________平均電圧:%lf(V)\n",year,month,j,fuusoku,fuuko,denatu);
__printf("平均発電電力:%lf(kW)\n発電電力量:%lf(kWh)\nCO2削減量:%lf(kg-c)\n"
,denryoku1,denryoku2,co2);
__if((fpout=fopen(fname2,"a"))==NULL){
___printf("ファイルに追記できません。--- %s\n",fname2);
___exit(EXIT_FAILURE);
__}
__fprintf(fpout,"%d/%d/%d,%lf,%lf,%lf,%lf,%lf,%lf\n",year,month,j,fuusoku,fuuko,denatu,denryoku1
,denryoku2,co2);
__printf("以上の結果を記録しました。 --- %s",fname2);
__fclose(fpout);
}
_return EXIT_SUCCESS;
}
void str_copy(char dst[],char src[])
{
_int i;
_for(i=0;src[i]!='\0';i++){
__dst[i]=src[i];
_}
_dst[i]='\0';
}
void str_cat(char dst[],char src[])
{
_int i,j;
_for(i=0;dst[i]!='\0';i++)
;
_for(j=0;src[j]!='\0';j++,i++){
_dst[i]=src[j];
_}
_dst[i]='\0';
}
>>for(j=1;j<=month1;j++){…}
のループについて、1週目は問題なく動くのですが、2週目の
>>for(kensuu = 0; fscanf(fpin, "%[^,],%lf,%lf,%lf,%lf,%lf,%lf\n", data[kensuu].jikoku, &data
[kensuu].fuusoku,&data[kensuu].fuuko, &data[kensuu].denatu, &data[kensuu].denryoku1,
&data[kensuu].denryoku2, &data[kensuu].co2) != EOF; kensuu++);
で止まる(というより無限ループになる?)ようです。このfor文の中でprintfを使い調べたところ、どうやらfscanfに問題があるということは分かりました。しかし、なにぶん最近勉強しはじめたばかりで、どこがどう悪いのか、見当もつきません(泣)
次から次へと大変恐縮ですが、心当たり程度でも結構ですので、ご意見をお願いします!
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
きちんと確認できていませんが、怪しいところといえばfscanf()の
"%[^,],%lf,%lf,%lf,%lf,%lf,%lf\n",
の最後の\nは不要かと思います。
scanf系は空白文字をデフォルトの区切り文字にしてるはずなので。
No.3
- 回答日時:
fscanfが怪しいって思っているなら、まずはそれを確認しましょう。
あとは、趣味の問題ではあるけど
なんで、str_catとstr_copyを作ったんです?標準ライブラリのstrcat,strcpy使えばいいんじゃないですか?
標準ライブラリ使いたくないなら、なんでfscanfやprintf等を使うんですか?
前回指摘がありましたが、sprintfの使い方がもったいないです。
> sprintf(fname2,"%s%s%s%s%s%s",path1,year2,path2,month2,path3,wfname);
こんなのこそstrcatの出番だと思うんですが。
sprintfだと%sと引数の組合せを間違えてもコンパイルエラーにはならないので、思わぬ失敗になることがありますが、strcatなら確実に必要な分だけ連結できるのですから。strncatでオーバーラン防止もできるし。
No.2
- 回答日時:
Cコンパイラは何を使っているのかな?
変数kensuuがint型で定義されてますが、dataの配列が86450となっています。
もし使用しているコンパイラのint型が-32768~32767の場合、dataの件数が86450個なら、メモリを壊していることになります。
この場合kensuuをlong型で定義しないと動かないと思います。
No.1
- 回答日時:
「fscanfに問題があるということは分かりました」というなら, 例えば fscanf が実際にどのような値を返しているのかくらい調べて当然ではないですかね. もちろん, fscanf がどのような状況のときにどんな値を返すのかも (知らないのであれば) 調べるのが当たり前.
そういうところから「どこがどう悪いのか」の検討をつけていくんだよ.
以下前の質問のやり取りに関して苦言を 1つ.
「CSVファイルのデータは86400秒分でも、その上にも行があるのだから、data[86400]では足りないのは当然ですね(笑)」
とか書いてますが, 「その上にも行がある」のは「当然」でもなんでもありません. 質問に書かれていない以上, むしろそれは「あなた以外のだれにとっても当然ではない」のです.
しかし, この str_copy だの str_cat だのの羅列は何とかならんものかねぇ....
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C++で指定文字列のカウント方法...
-
char型2つを結合し、short型に...
-
バイナリファイル(画像)のよみ...
-
printf による16進表示について
-
C言語プログラムで、ループがう...
-
#defineが使用するメモリ領域に...
-
C言語のtime_tに関して
-
[C]セグメンテーションエラー:...
-
文字列の入力
-
VC++でSQLへSELECT文を送ったの...
-
複数桁10進数の*桁目だけを抽出...
-
Aの値からBの値を除するとは??
-
main.c:7:43: warning: implici...
-
「Aに対するBの割合」と「Aに対...
-
エクセルで可視セルにのみ値貼...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語での引数の省略方法
-
ExcelでPC(パソコン)によって...
-
「指定されたキャストは有効で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
【C言語】全角文字の配列を、全...
-
#defineが使用するメモリ領域に...
-
エラーについて質問です。
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
プログラミングの授業の課題です
-
csvファイルの読み取り
-
Cプログラムについて
-
strtok
-
矢印キーを押下してコンソール...
-
C言語で複数列のデータを1列の...
-
ポインタと配列
-
構造体メンバの初期化
-
言語Cについて教えていただけま...
-
C++で指定文字列のカウント方法...
-
小数の指数表示
-
VC++でSQLへSELECT文を送ったの...
-
reallocでエラー
-
ファイル
おすすめ情報