VC++でコンパイルし、実行時にエラーが出ます。
以下のようなエラーが出て、「致命的なエラーです」と表示され実行されません。
Dbug Assertion Failed!
File:f:\(中略)\fgetc.c
Expression: stream != NULL
自分はstdio.hをインクルードして、fopenやsprintf,fgets,fgetcを使用していますが問題があるのでしょうか?
warningが出ても「これより安全な関数が準備されてますよ」という忠告にしか捕らえてませんでした。
以下はfgetcを使っている部分です。
FILE *fp;
char buf1;
int bug2;
fp = fopen("../../dat/csv/teki_dat/teki01.txt", "r");
buf1 = buf2 = fgetc(fp);
while(fgetc(fp)!='\n');
どこがおかしいところがあればご指摘をお願いいたしますm(__)m
VC++で実行時のエラー
Re:VC++で実行時のエラー
おそらくfopenに失敗したのにfgetcを実行したためでしょう。
fopenは失敗することもあります(ファイルが存在しなかったりパスが間違っていたりファイルが使用中とか権限がないとか)。
失敗するとNULLを返しますのでfopenの戻り値をチェックするようにしましょう。
fopenは失敗することもあります(ファイルが存在しなかったりパスが間違っていたりファイルが使用中とか権限がないとか)。
失敗するとNULLを返しますのでfopenの戻り値をチェックするようにしましょう。
fp = fopen("../../dat/csv/teki_dat/teki01.txt", "r"); if (fp == NULL) { printf("ファイルのオープンに失敗しました\n"); } else { buf1 = buf2 = fgetc(fp); while(fgetc(fp) != '\n'); fclose(fp); }
Re:VC++で実行時のエラー
toyoさん、ありがとうございます。
おっしゃる通りでファイルパスが間違えていました。
"../../dat/csv/teki_dat/teki01.txt"
↓
"dat/csv/teki_dat/teki01.txt"
としたらファイルを読み込めました。
ですが、fopenを使っている関数(state.c)からteki01.txtの相対パスは最初の書き方です。
結果から見るとfopenでファイルを開く場合はprojectから見た相対パスを書かなければいけないのでしょうか?
前まではprojectと同じ階層に.cのソースファイルは置いていたためか問題なく動いていたのでfopenを使った関数がある場所からの相対パスと思い込んでいました。
おっしゃる通りでファイルパスが間違えていました。
"../../dat/csv/teki_dat/teki01.txt"
↓
"dat/csv/teki_dat/teki01.txt"
としたらファイルを読み込めました。
ですが、fopenを使っている関数(state.c)からteki01.txtの相対パスは最初の書き方です。
結果から見るとfopenでファイルを開く場合はprojectから見た相対パスを書かなければいけないのでしょうか?
前まではprojectと同じ階層に.cのソースファイルは置いていたためか問題なく動いていたのでfopenを使った関数がある場所からの相対パスと思い込んでいました。
root | |-project | |-dat | |-csv | |-teki_dat | |-teki01.txt | |-my_dat | |-source | |-state.c
Re:VC++で実行時のエラー
> 結果から見るとfopenでファイルを開く場合はprojectから見た相対パスを書かなければいけないのでしょうか?
ソースファイルもプロジェクトファイルも関係ありません。
相対パスは,必ずカレントディレクトリからの相対として解決されます。
実行ファイルからの相対パスを指定したいのであれば,GetModuleFileName Win32APIなどを使って実行ファイルの位置を取得し,そこからの相対パスとして絶対パスを組み立てる必要があります。
MSDN: GetModuleFileName Function (Windows)
http://msdn.microsoft.com/en-us/library/ms683197.aspx
MSDN: PathCombine Function ()
http://msdn.microsoft.com/en-us/library/bb773571.aspx
ちなみに,カレントディレクトリは簡単に変更されます。
たとえば,ショートカットの作業フォルダはカレントディレクトリの初期値になります。
ソースファイルもプロジェクトファイルも関係ありません。
相対パスは,必ずカレントディレクトリからの相対として解決されます。
実行ファイルからの相対パスを指定したいのであれば,GetModuleFileName Win32APIなどを使って実行ファイルの位置を取得し,そこからの相対パスとして絶対パスを組み立てる必要があります。
MSDN: GetModuleFileName Function (Windows)
http://msdn.microsoft.com/en-us/library/ms683197.aspx
MSDN: PathCombine Function ()
http://msdn.microsoft.com/en-us/library/bb773571.aspx
ちなみに,カレントディレクトリは簡単に変更されます。
たとえば,ショートカットの作業フォルダはカレントディレクトリの初期値になります。
Re:VC++で実行時のエラー
YuOさん、返信ありがとうございます。
全く勘違いをしていたみたいです。
サイトの紹介をしてもらっていて悪いのですが、Win32APIは知識がないため使えないのでカレントディレクトリからの相対パスを指定することにします。
全く勘違いをしていたみたいです。
サイトの紹介をしてもらっていて悪いのですが、Win32APIは知識がないため使えないのでカレントディレクトリからの相対パスを指定することにします。