ページ 1 / 1
ファイルの存在の確認
Posted: 2010年3月16日(火) 01:32
by 白狐の子
現在,入力した文章を○○.txt(○○は任意)に書き込むプログラムを作っています。
その際、ファイルが既にあるかどうかを調べ、ある場合は上書きするかどうかを聞く、という風にしたいと思っています。
ここでファイルが既にあるかを確認する方法としてに、思いついたのが
FILE *fp;
fp = fopen("○○.txt","r");
if(fp!=NULL){
printf("ファイルが既にあります。上書きしますか?");
・
・
・
のようにfopenを読み込み専用で開こうとして、その値がNULLかどうかでファイルの存在を確認するものです。
ここで疑問に思ったのですが、fopen("○○.txt","r"); はファイルが存在しないときのみ、NULLを返すのでしょうか?
それ以外にあるとすると、思いがけないバグがおきそうなので不安です。
また、もしこの方法以外にファイルの存在を確認する方法があったら教えていただけないでしょうか?

Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 01:46
by たかぎ
処理系不明の状況では、いったんオープンしてみるしかありません。
NULLが変える状況も処理系に依存します。
例えば、UNIXであれば、パーミッションが読み込み可能になっていない場合にはNULLが返るはずです。
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 12:19
by 白狐の子
処理系に依存するのですか
ちゃんと環境まで書いておけばよかったですね、すいません。
とりあえず、自分が今使っている環境で想定外の事態がおこらなければいいので
OS : Windows
コンパイラ : VC++ 2008EE
この環境の場合だと、どうでしょうか?
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 12:43
by たかぎ
> 処理系に依存するのですか
> ちゃんと環境まで書いておけばよかったですね、すいません。
利用規約でそう決められているはずです。
ですので、処理系を書いていなければ、処理系に依存しない規格厳密合致プログラミングの話だと受け取るしかありません。
まさか、規約を読んでいないということはありませんよね?
> OS : Windows
> コンパイラ : VC++ 2008EE
> この環境の場合だと、どうでしょうか?
_stat関数でも使うのが一番手っ取り早いのでは?
_accessや_access_sでもよい気がしますが、ディレクトリかどうかの判別ができなくなります。
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 13:22
by 白狐の子
規約は読みました。
ただ、勝手な判断で書かなかったので、完全にこちらが悪いです。すいません。今後気をつけます。
_stat関数ですか。初めて知りました。
調べて組み込んでみたところうまくいきました。ありがとうございます。
加えて、もうひとつ質問なのですが
int _stat(
const char *path,
struct _stat *buffer
);
の、struct _stat *buffer の構造体はメンバがいろいろありますが
このメンバのうちひとつでも、読み込めない=エラー
という解釈で問題ないでしょうか?
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 13:31
by Blue
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 13:37
by たかぎ
> 戻り値とerrnoが全てなのでは?
そんなことはありません。
st_modeを調べて、それがディレクトリでないことを確認する必要があります。
ディレクトリだと、その名前が存在するという結果になりますが、当然fopenでは開けません。
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 13:48
by Blue
>st_modeを調べて、それがディレクトリでないことを確認する必要があります。
あぁ、確かにそうでしたね。
Re:ファイルの存在の確認
Posted: 2010年3月16日(火) 13:50
by たかぎ
一応、モードに"r"を指定した場合にfopenに失敗する可能性をもう少し詳しく書いておきます。
・ファイルが存在しない
・読み込み許可がない(Windowsでもありますね)
・ディレクトリを指定した
・FOPEN_MAX以上のファイルをオープンしようとした
・バッファを割付けようとしてmallocに失敗した
・ドライブが破損している
こんなところでしょうか。
Re:ファイルの存在の確認
Posted: 2010年3月17日(水) 21:27
by 白狐の子
回答ありがとうございます。
いろいろ試したところ、結局stat関数を使うことに決めました。