ページ 11

ファイル処理について

Posted: 2009年1月07日(水) 15:16
by mi
こんにちは、はじめまして。
ファイル処理で少し躓いているので質問させて下さい。

FileReadというファイルを読み込む関数があるのですが、
グローバル変数としてchar FileAddress[40]と宣言し、
その変数を使ってFileReadで処理をさせたいです。
例えば、
char FileAddress[40];

void Initialize(void)
{
strcpy(FileAddress, "test.txt");
}

void FileRead(void)
{
FILE *fp;
fp = fopen(FileAddress, "r");
}
というようにしたいのですが、
Microsoft Visual Studio C ランタイム ライブラリは致命的なエラーを検出しました。
と出てしまいます。
ですが、
char FileAddress[40];

void FileRead(void)
{
FILE *fp;
strcpy(FileRead, "test.txt");
fp = fopen(FileAddress, "r");
}
この場合、エラーは出ず、普通に動作します。
ヘッダはstring.hとstdio.hをインクルードしていますし、
関数の呼び出し順も間違っていないと思います。
原因がさっぱりわかりません;

コンパイラはVC++ 2008EEです。

Re:ファイル処理について

Posted: 2009年1月07日(水) 15:18
by mi
タグの使い方が違ったのかな;
見づらくなってしまってすいません。

Re:ファイル処理について

Posted: 2009年1月07日(水) 15:36
by kazuoni
まず、
void FileRead(void)
でちゃんとfcloseしていますか?
fpはFileReadのみで有効です。

以下はvisual c++,vistaで動作確認済みです
#include<stdio.h>
#include<string.h>
 
char arr[100];

void copy(void)
{
	strcpy(arr,"test.txt");
}

void FileRead(void)
{
	char str[100];
	FILE *fp;
	fp = fopen(arr, "r");
        if(fp)
        {
	      fscanf(fp,"%s",str);
	      printf("%s",str);
	      fclose(fp);
        }
        else
              printf("fread_error");
}

int main(void)
{
	copy();
	FileRead();
	return 0;
}

赤:追加

Re:ファイル処理について

Posted: 2009年1月07日(水) 15:38
by dic
#include <string.h>

char FileAddress[40];

void Initialize(void)
{
//	strcpy(FileAddress, "test.txt");
	strcpy_s(FileAddress, "test.txt");
}

void FileRead(void)
{
	FILE *fp;
//	fp = fopen( FileAddress, "r" );
	fopen_s( &fp, FileAddress, "r");

	if( fp )
		fclose( fp );
}

int _tmain(int argc, _TCHAR* argv[/url])
{
	Initialize();
	FileRead();

	return 0;
}
こうでしょうか?
エラーが発生しませんでしたが
デバッカで一行ずつ実行されてみてはいかがでしょうか?

Visual C++ 2008 EE

Re:ファイル処理について

Posted: 2009年1月07日(水) 15:45
by kazuoni
あ、fcloseと書かなくても動作しますね^^;
んん~確かに、dicさんの言うように、ブレイクポイント立てて動作を見るのが
一番はやく解決できると思いますが。。
あと、fopenの読み込みエラーは書いておいたほうがよいと思います。
(自分のにも書いていませんので、追加しておきます。^^;)

Re:ファイル処理について

Posted: 2009年1月07日(水) 15:50
by SCI
#include <stdio.h>

char FileAddress[40];

void Initialize(void)
{
	strcpy(FileAddress, "test.txt");
}

void FileRead(void)
{
	FILE *fp;
	fp = fopen(FileAddress, "r");
}

int main(void)
{
	Initialize();
	FileRead();
	return 0;
}
これ、動きましたよ?BCCですが・・・
ということは、コード的には問題ないはずです。
やはりVCは謎いっぱいってことですかね。

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:35
by mi
kazuoniさん、dicさん、SCIさん
お返事ありがとうございます。

ソースなんですが、他の処理がいろいろ書いてあるので
かなり端折ってあります。
fcloseを書き忘れていたようで申し訳ないです;

実際には
void FileRead(void)
{
   FILE *fp;
   fp = fopen(FileAddress, "r");
   if(fp == NULL)
   {
      fclose(fp);
   }

   //処理

   fclose(fp);
}
となっています。
dicさんのようにfopen、strcpy等を変えてみましたが、
warningが消えたのみです。

またブレークポイントで動作を見たのですが、
if(fp == NULL)
   {
      fclose(fp);  ←ここ
   }
でエラーになるようです;

エラーの内容ですが

Debug Assertion Failed!

Program: ...sual Studio 2008\Projects\Test\Test.exe
File:f:\dd\vctools\crt_bld\self_x86crt\src\fclose.c
Line: 47

Espression:(stream != NULL)

For infomation on how your program can cause an assertion
failuer,see the Visual C++ documentation on asserts

(ながながとすみません)となっているので
fcloseが原因のようなのですが…。

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:40
by バグ
ファイルポインタがNULLなのに、クローズ処理をしているからではないでしょうか?

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:42
by Mist
fp == NULLということは「ファイルを開くのに失敗」しているのだからfcloseする必要はないししてはいけません。

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:43
by kazuoni
そのfcloseの処理で
fscanf,fgets,fgetcを使っていませんか?
たぶんそれでうまく処理ができていないと思うのですが。
自分の予期した通りにそこまで動いていますか?
文字列読み取り時のfpの動きをひとつずつ見ていってみてください。

空白文字、改行文字の問題だと思います。

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:45
by kazuoni
あ、↑は無視してください^^;
fpがNULLのときは閉じれないですよね^^;

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:45
by mi
なるほど、fcloseではなくreturnやexitにすべきですね。
でも、if(fp == NULL)を通るってことは
ファイルが読み込めていないんですよね;

Re:ファイル処理について

Posted: 2009年1月07日(水) 16:48
by Mist
> ファイルが読み込めていないんですよね;

ちょっと違う。
「ファイルを開くことに失敗している」が正しいです。
開こうとしているファイルはexeと同じフォルダにありますか?(カレントディレクトリを変更していなければ)

Re:ファイル処理について

Posted: 2009年1月07日(水) 17:00
by dic
void FileRead(void)
{
   FILE *fp;
   fp = fopen(FileAddress, "r");
   if(fp == NULL)
   {
      fclose(fp);   // ← ここで1回
   }

   //処理

   fclose(fp);  // ← ここで2回
}
2回 fclose() してます
また、ファイルを開くのを失敗した時にも fclose() します

Re:ファイル処理について

Posted: 2009年1月07日(水) 17:01
by mi
なるほど、ファイルを開くことに失敗しているですか…。
あとは何か簡単なミスをしている感じですね。
もう少し自力で頑張ってみます。
どうしてもわからなければ、また質問させて下さい。

皆さんお付き合いいただきありがとうございました。