ページ 11

fscanfが正しく出力できません

Posted: 2014年7月27日(日) 19:15
by kehos12
実験上必要なデータをcsvファイルとして出力し、その値を別のプログラムで用いるためにfscanff関数を使いました。
しかし数値がすべて0となってしまっています。
初期化しないとすべての値がぶっ飛んで表示されるため個人的にはfscanf関数が動作していないのではないかと考えました。
この原因および解決策をご教授いただきたいです。
以下二通りの方法で試したソースを張っておきます。
また、3つ目のソースは別プログラムの今回読み込もうとしているcsvファイルを作成している過程です。
概要としてはDCT後に正規化、二値化した64×64画素の行列で、うまくいくと0と255が組み合わさった行列が出力されるはずで、csvファイルにはきれいに出力されております。
お手数ですがよろしくお願いします。

コード:

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


int main (void)
 {
 int i,j;
 double val[64][64];
 int block=64;
 FILE *fp,*fp2;
  fp=fopen("45.csv","r");
 
 for(i=0;i<block;i++){
	 for(j=0;j<block;j++){
		 fscanf(fp,"%f",&val[i][j]);
	 }
 }
 fp2=fopen("452.csv","w");

 for(i=0;i<block;i++){
 for(j=0;j<block;j++)fprintf(fp2,",%f",val[i][j]);
 fprintf(fp2,"\n");
 }
 fclose(fp);
 fclose(fp2);
 return 0;
 }

コード:

#include <stdio.h>
#include <stdlib.h>
#include "opencv/cv.h"
#include "opencv/cxcore.h"
#include "opencv/highgui.h"

int main(void){
	FILE *fp,*fp2;
	int i,j;	
	IplImage* val=0;
	val=::cvCreateImage(cvSize(64, 64), IPL_DEPTH_8U, 1);
	cvNamedWindow("val", CV_WINDOW_AUTOSIZE);
	int block=64;
	fp=fopen("45.csv","r");
	fp2=fopen("g.csv","w");
	for(i = 0; i <  block; i++){
		for(j = 0; j <  block; j++){
			fscanf(fp,"%lf",val->imageData[i* val->widthStep +j]);
			fprintf(fp2,",%lf",val->imageData[i* val->widthStep +j]);
  }
		fprintf(fp2,"\n");
 }
	::cvShowImage("val",val);
	::cvReleaseImage(&val);
	::cvDestroyWindow("val");
}

コード:

void ShowDCTImage(double **dst, int Width, int Height, double Amp, char* WindowName){
	FILE *f;
	f=fopen("TheoreticalValue.csv","w+");

	IplImage*GrayDstImage=::cvCreateImage(cvSize(Width, Height), IPL_DEPTH_8U, 1);
	char FileName[260] = {0};
	double Maximum = 0.0;
	double Minimum = 0.0;
	double Temp = 0.0,Temp2=0.0;
	int block=64;
	
	for(int i = 0; i <block; i++){
		for(int j = 0; j <block; j++){
			Temp = (dst[i][j] < 0)?(-1.0)*dst[i][j]:dst[i][j];
			if(Maximum < Temp){
			Maximum = Temp;
			}
		}
	}
	Maximum /= 255.0 * Amp;
				for(int a = 0; a < block; a++){
					for(int b = 0; b < block; b++){
					Temp = (dst[a][b] < 0)?(-1.0)*dst[a][b]:dst[a][b];
					Temp2=(unsigned char)(Temp/Maximum );
					if(Temp2>100)Temp2=255;
					else Temp2=0;
					GrayDstImage->imageData[a * GrayDstImage->widthStep +b] = Temp2;
					fprintf(f,",%f",Temp2);
				}
				fprintf(f,"\n");
	sprintf(FileName, "%s.png", WindowName);
	}
	::cvSaveImage(FileName, GrayDstImage);
	::cvNamedWindow(WindowName);
	::cvShowImage(WindowName, GrayDstImage);
	::cvReleaseImage(&GrayDstImage);
	fclose(f);
}


Re: sprintfが正しく出力できません

Posted: 2014年7月27日(日) 19:18
by みけCAT
本当にfprintf関数またはsprintf関数の問題ですか?
最初のコードの15行目のfscanf関数に渡している書式が間違っているせいではないですか?
もしくは、fscanfの読み込みが入力に含まれるカンマで止まっているのではないですか?

Re: sprintfが正しく出力できません

Posted: 2014年7月27日(日) 19:20
by kehos12
申し訳ありません、間違えました・・・。
fprintfをすべてfscanfに置き換えて呼んでいただきたいです・・・・。
その15行目の問題についてもう少しお伺いしても良いですか?

Re: sprintfが正しく出力できません

Posted: 2014年7月27日(日) 19:21
by みけCAT
kehos12 さんが書きました:その15行目の問題についてもう少しお伺いしても良いですか?
fscanf関数でdouble型の値を読み込む場合は、%fではなく%lfを用いるべきだと思います。

Re: fscanfが正しく出力できません

Posted: 2014年7月27日(日) 19:27
by kehos12
みけCATさん
ご指摘どうもありがとうございますm(__)m
しかし残念ながら改善することができませんでした。

コード:

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


int main (void)
 {
 int i,j;
 double val[64][64]={0,0};
 int block=64;
 FILE *fp,*fp2;
  fp=fopen("45.csv","r");
 
 for(i=0;i<block;i++){
	 for(j=0;j<block;j++){
		 fscanf(fp,"%lf",&val[i][j]);
	 }
 }
 fp2=fopen("452.csv","w");

 for(i=0;i<block;i++){
 for(j=0;j<block;j++)fprintf(fp2,",%f",val[i][j]);
 fprintf(fp2,"\n");
 }
 fclose(fp);
 fclose(fp2);
 return 0;
 }
ほかにも出力をint 型にしてint型で読み込みなどで試してみたのですがだめでした・・・。

Re: fscanfが正しく出力できません

Posted: 2014年7月27日(日) 19:48
by box
試しに、こんなコードを書いてみて、

コード:

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

#define BLOCK (2)

int main(void)
{
    FILE *fp, *fp2;
    double v[BLOCK][BLOCK];
    int i, j;

    fp = fopen("45.csv", "r");
    if (fp == NULL) {
        fprintf(stderr, "file open error.\n");
        exit(1);
    }
    for (i = 0; i < BLOCK; i++) {
        for (j = 0; j < BLOCK; j++) {
            fscanf(fp, "%lf,", &v[i][j]);
        }
    }
    fclose(fp);

    fp2 = fopen("452.csv", "w");
    if (fp2 == NULL) {
        fprintf(stderr, "File open error.\n");
        exit(1);
    }
    for (i = 0; i < BLOCK; i++) {
        for (j = 0; j < BLOCK; j++) {
            fprintf(fp2, "%f%s", v[i][j], (j == BLOCK - 1) ? "" : ",");
        }
        fprintf(fp2, "\n");
    }
    fclose(fp2);
    return 0;
}

コード:

1,2
3,4
っていうファイルを食わせたら、

コード:

1.000000,2.000000
3.000000,4.000000
っていう結果を得ました。

# 字下げをちゃんとしましょう。

Re: fscanfが正しく出力できません

Posted: 2014年7月27日(日) 20:12
by kehos12
boxさん
ご指摘をどうもありがとうございます。
まず自身で他のscvファイルでの確認すべきでした。
申し訳ありません。
boxさんに書いていただいたコードで行列数のみを変えて動かしたところ
結果は変わりませんでした。
ファイルを出力する段階でも問題かもしれませんが、
とりあえずは別の方法での解決策を考えることにしました。
みなさん御協力ありがとうございましたm(__)m
またなにかあったときに質問をさせていただくのでそのときはよろしくお願いいたします。

Re: fscanfが正しく出力できません

Posted: 2014年7月27日(日) 20:53
by かずま
自分で 45.csv のファイルを見ていないんですか?

fprintf(fp2, ",%f", val[j]); で書き出したのなら
数値の前に必ず ',' がついているはずです。

例えば、
,52.34000,0.003500,127.50000, ...

そんなものを fscanf の "%lf" だけで読めるはずはありません。

" ,%lf" としてみてください。
, の前のスペースを忘れると、改行コードを読み飛ばせません。

Re: fscanfが正しく出力できません

Posted: 2014年7月27日(日) 22:40
by kehos12
かずまさん
御指摘ありがとうございました、おかげさまで目的の動作をするプログラムになりました。
初歩的なことだったようでお恥ずかしいですが自分で気づくことはできなかったと思います。
大変助かりましたm(__)m
説明もわかりやすく自分なりに納得することもできました。
どうもありがとうございました。
また是非よろしくお願いいたします。