自作関数を用いたファイル読み込み時にエラーが出る

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

自作関数を用いたファイル読み込み時にエラーが出る

#1

投稿記事 by KEITO » 8年前

[1] 質問文
 [1.1] csvファイルから3次元配列に値を読み込む(x方向、y方向、z値)関数を自作関数で作制したい。
 [1.2]  void関数でファイル名、csv中の列のサイズ、値を渡す配列を引数で渡し、値を読み取らせるようにした。

読み込みの関数

コード:

void read_file(char *filename,int SIZE,double histgram[1000][256][3]){
	int p;
    int ret,cnt=0;
    int x=0,y=0;
    double temp;

    printf( "%s is not found\n", filename );
    
   
	FILE *fp;
    fp = fopen( filename, "r" );

    
    if( fp == NULL ){
            printf( "%s is not found\n", filename );
    }

    printf("start\n");
	
	while((p = getc(fp)) != EOF && cnt < 30) {
		if(p == '\n'){
			cnt++;
		}
	}

	for(x=0;x<800;x++){
    	for(y=0;y<SIZE;y++){
    		if(fscanf( fp, "%lf,", &temp)!='\0');
    		histgram[x][y][0] = x*50.0;
    		histgram[x][y][1] = y*50.0;
    		histgram[x][y][2] = temp*1000.0;
    		
    	}
    }
    fclose(fp);
    
}
*メイン関数

コード:

int main(int argc, char* argv[]){
     int SIZE = 256;
     double histgram[1000][256][3] = {0.0};

	printf("Input sizeof let:");
	scanf("%d",&SIZE);

	//ファイル読み込み
	read_file(argv[1],SIZE,histgram);
	//ファイル読み込み終了
 
    return 0;
}
*エラーコード
*** starting debugger for pid 4080, tid 5976
1 [main] bead2 4080 try_to_debug: Failed to start debugger, Win32 error 2
*** continuing pid 4080 from debugger call (0)
*** starting debugger for pid 4080, tid 5976
3114 [main] bead2 4080 try_to_debug: Failed to start debugger, Win32 error 2
*** continuing pid 4080 from debugger call (0)
3540 [unknown (0x724)] bead2 4080 cygwin_exception::open_stackdumpfile: Dumping stack trace to bead2.exe.stackdump

*stackdumpファイル内
Exception: STATUS_STACK_OVERFLOW at rip=001004027F6
rax=00000000003E4038 rbx=000000000024CB20 rcx=0000000000053AC8
rdx=000000000024CB20 rsi=000000060003A070 rdi=0000000000000001
r8 =00000006000281A0 r9 =0000000000000000 r10=0000000000000040
r11=0000000000000000 r12=0000000000000000 r13=0000000000000001
r14=000000000024CB66 r15=000000000024CB66
rbp=000000000024CBC0 rsp=000000000024CAB0
program=D:\bead2.exe, pid 4080, thread unknown (0x724)
cs=0033 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame Function Args
0000024CBC0 001004027F6 (00100402EDC, 0000024CB20, 0060003A070, 00180048410)
0000024CBC0 000005DC038 (0000024CB20, 0060003A070, 00180048410, 00000000001)
0000024CBC0 00000000002 (0060003A070, 00180048410, 00000000001, 00000000020)
0000024CBC0 00100402EDC (00000000020, FF0700010302FF00, 0018004839F, 0000024D680)
0000024CBC0 00180048410 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 001800460DC (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00180046174 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 001004028D1 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 00100401010 (00000000000, 00000000000, 00000000000, 00100401000)
00000000000 7FF9F61A2D92 (00000000000, 00000000000, 00000000000, 00000000000)
00000000000 7FF9F87A9F64 (00000000000, 00000000000, 00000000000, 00000000000)
End of stack trace

[1] 質問文
 [1.1] 自分が今行いたい事は何か
   ファイル読み込みを行う自作関数を作りたい
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
   コード記載しました
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
   エラーの記載をしました
   ファイル読み込み部でエラーが出るようです
 [1.4] 今何がわからないのか、知りたいのか
 エラーが出る原因と解決策(main関数で実行すれば読み込みできましたが、できれば自作関数内で行いたい)
[2] 環境  
 [2.1] OS : Windows10
 [2.2] コンパイラ名 : gcc-4.9.3 Cygwin環境

[3] その他
 ・どの程度C言語を理解しているか
  基本レベル(工学科大学1年生レベル)
 ・ライブラリを使っている場合は何を使っているか
  ライブラリ不使用

ご享受いただけましたら幸いです。
よろしくお願いいたします。

box
記事: 2002
登録日時: 13年前

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#2

投稿記事 by box » 8年前

KEITO さんが書きました:

コード:

    int ret,cnt=0;
使わない変数はサクッと消しておきましょう。
KEITO さんが書きました:

コード:

    printf( "%s is not found\n", filename );
7行目のこれは、不要でしょう。
KEITO さんが書きました:

コード:

	while((p = getc(fp)) != EOF && cnt < 30) {
		if(p == '\n'){
			cnt++;
最初と同じ。cntを後ろの方で使っていませんので、そもそも不要では?
KEITO さんが書きました:

コード:

    		if(fscanf( fp, "%lf,", &temp)!='\0');
最後のセミコロンはひじょうにマズいと思います。また、'\0'と比較しているのもマズいと思います。
あと、このif文の条件が真のとき、どこからどこまでを実行したいのですか?
適切に
{

}
とで囲む必要はありませんか?
KEITO さんが書きました:

コード:

     int SIZE = 256;
どうせ後でscanfで値を放り込んでいるので、ここでの初期化に意味はありません。
KEITO さんが書きました:

コード:

	scanf("%d",&SIZE);
SIZEの値はいくつですか?
KEITO さんが書きました:

コード:

	read_file(argv[1],SIZE,histgram);
argv[1]が必ず存在することを前提にしてはいけません。argcが2以上であることをチェックしましょう。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#3

投稿記事 by みけCAT » 8年前

KEITO さんが書きました:*stackdumpファイル内
Exception: STATUS_STACK_OVERFLOW at rip=001004027F6
スタックオーバーフローで落ちていると推測できます。
とりあえずの対策としては、main関数内のdouble histgramの前にstaticを付けて静的変数にしてください。
box さんが書きました:
KEITO さんが書きました:

コード:

	while((p = getc(fp)) != EOF && cnt < 30) {
		if(p == '\n'){
			cnt++;
最初と同じ。cntを後ろの方で使っていませんので、そもそも不要では?
おそらくヘッダを読み飛ばすという意味があり、不要ではない気がします。
ただし、ヘッダを読み飛ばす処理であると仮定した場合、ヘッダの次の行の1文字目も読み飛ばされるのはまずいかもしれません。
「cntを後ろのほうで使っていないので不要」ということは、例えば

コード:

#include <stdio.h>
int main(void) {
	int i = 0;
	while (i < 10) {
		printf("%d\n", i);
		i++;
	}
	return 0;
}
のiも不要だと考えられるということですか?
box さんが書きました:
KEITO さんが書きました:

コード:

     int SIZE = 256;
どうせ後でscanfで値を放り込んでいるので、ここでの初期化に意味はありません。
scanfで値が放り込まれるとは限りません。
scanfの戻り値をチェックするべきです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#4

投稿記事 by box » 8年前

まあ細かい部分はさておき、絶対直しておくべきところだけでも直しておきましょう。>質問者さん
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

KEITO

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#5

投稿記事 by KEITO » 8年前

box様、みけCAT様
返信ありがとうございます。
box さんが書きました:
KEITO さんが書きました:

コード:

    int ret,cnt=0;
使わない変数はサクッと消しておきましょう。
こちらについては、main内で別の処理で使うため消し忘れていました。
みけCAT さんが書きました:
KEITO さんが書きました:*stackdumpファイル内
Exception: STATUS_STACK_OVERFLOW at rip=001004027F6
スタックオーバーフローで落ちていると推測できます。
とりあえずの対策としては、main関数内のdouble histgramの前にstaticを付けて静的変数にしてください。
staticをつけることでエラー回避できましたありがとうございます。
みけCAT さんが書きました:
box さんが書きました:
KEITO さんが書きました:

コード:

	while((p = getc(fp)) != EOF && cnt < 30) {
		if(p == '\n'){
			cnt++;
最初と同じ。cntを後ろの方で使っていませんので、そもそも不要では?
おそらくヘッダを読み飛ばすという意味があり、不要ではない気がします。
ただし、ヘッダを読み飛ばす処理であると仮定した場合、ヘッダの次の行の1文字目も読み飛ばされるのはまずいかもしれません。
「cntを後ろのほうで使っていないので不要」ということは、例えば

コード:

#include <stdio.h>
int main(void) {
	int i = 0;
	while (i < 10) {
		printf("%d\n", i);
		i++;
	}
	return 0;
}
のiも不要だと考えられるということですか?
こちらについてはみけCAT様がおっしゃったとおり、ヘッダ回避のためにつけました。
ただし、確認したところ1文字目(ここでは数字の符号)が読み飛ばされていました。
こちらについてはどうしたら回避できますでしょうか?
みけCAT さんが書きました:
box さんが書きました:
KEITO さんが書きました:

コード:

     int SIZE = 256;
どうせ後でscanfで値を放り込んでいるので、ここでの初期化に意味はありません。
scanfで値が放り込まれるとは限りません。
scanfの戻り値をチェックするべきです。
こちらはファイル読み込み関数内で値を確認を行い、値が渡されていることを確認しました。
box さんが書きました:
KEITO さんが書きました:

コード:

    		if(fscanf( fp, "%lf,", &temp)!='\0');
最後のセミコロンはひじょうにマズいと思います。また、'\0'と比較しているのもマズいと思います。
あと、このif文の条件が真のとき、どこからどこまでを実行したいのですか?
適切に
{

}
とで囲む必要はありませんか?
ご指摘ありがとうございます。
おっしゃる通り、セミコロンではなく、{}で値を代入する部分を囲みました。
'\0'の部分は'\n'と比較をするよう変更を行いました。

よろしくお願いいたします。

改変コード

コード:

void read_file(char *filename,int SIZE,double histgram[1000][256][3]){
	int p;
    int cnt=0;
    int x,y;
    double temp;
   
	FILE *fp;
    fp = fopen( filename, "r" );

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

	while((p = getc(fp)) != EOF && cnt < 30) {
		if(p == '\n'){
			cnt++;
		}
	}

	for(x=0;x<800;x++){
    	for(y=0;y<SIZE;y++){
    		if(fscanf( fp, "%lf,", &temp)!='\n'){
	    		histgram[x][y][0] = x*50.0;
	    		histgram[x][y][1] = y*50.0;
	    		histgram[x][y][2] = temp*1000.0;
    		}
    	}
    }
	
    fclose(fp);
    
}

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#6

投稿記事 by みけCAT » 8年前

KEITO さんが書きました:ただし、確認したところ1文字目(ここでは数字の符号)が読み飛ばされていました。
こちらについてはどうしたら回避できますでしょうか?
文字を読み込むより前にcntのチェックをするようにすればいいと思います。

コード:

while(cnt < 30 && (p = getc(fp)) != EOF) {
KEITO さんが書きました:'\0'の部分は'\n'と比較をするよう変更を行いました。
ナンセンスですね。C言語であれば規格(N1256 5.2.1 Character sets)で全てのビットがゼロ(すなわち、0)と決まっている'\0'と比較したほうがまだマシでしょう。
入力がされたかを判定するには、

コード:

if(fscanf( fp, "%lf,", &temp)==1)
とするとよいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#7

投稿記事 by かずま » 8年前

csvファイルの各行の最後のデータには ',' が付かないのでは?

コード:

void read_file(const char *filename, int SIZE, double histgram[1000][256][3])
{
    int p;
    int cnt = 0;
    int x, y;
    double temp;

    FILE *fp = fopen(filename, "r");
    if (fp == NULL) exit(1);

    while ((p = getc(fp)) != EOF)
        if (p == '\n' && ++cnt == 30) break;

    for (x = 0; x < 800; x++) {
        for (y = 0; y < SIZE; y++) {
            if (fscanf(fp, "%lf%*c", &temp) == 1) {
                histgram[x][y][0] = x * 50.0;
                histgram[x][y][1] = y * 50.0;
                histgram[x][y][2] = temp * 1000.0;
            }
        }
    }
    fclose(fp);
}
"%*c" で読み飛ばしてみましたが、いかがでしょうか?

KEITO

Re: 自作関数を用いたファイル読み込み時にエラーが出る

#8

投稿記事 by KEITO » 8年前

みけCAT様

返信ありがとうございます。
みけCAT さんが書きました:
KEITO さんが書きました:ただし、確認したところ1文字目(ここでは数字の符号)が読み飛ばされていました。
こちらについてはどうしたら回避できますでしょうか?
文字を読み込むより前にcntのチェックをするようにすればいいと思います。

コード:

while(cnt < 30 && (p = getc(fp)) != EOF) {
KEITO さんが書きました:'\0'の部分は'\n'と比較をするよう変更を行いました。
ナンセンスですね。C言語であれば規格(N1256 5.2.1 Character sets)で全てのビットがゼロ(すなわち、0)と決まっている'\0'と比較したほうがまだマシでしょう。
入力がされたかを判定するには、

コード:

if(fscanf( fp, "%lf,", &temp)==1)
とするとよいでしょう。
ご指摘いただいた箇所を修正し、うまく動作することを確認しました。

かずま様
回答ありがとうございます。
いただいたコードでうまくいきました。

自身の勉強不足でお手を煩わせてしまい申し訳ありません。
ご指摘いただいた点について再度自身で勉強するよう致します。

回答していただいたbox様、みけCAT様、かずま様ありがとうございました。

閉鎖

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