ページ 11

ファイルが作成されない

Posted: 2010年9月19日(日) 15:22
by dic
下のコードを書いたのですが、fopen関数でファイルを生成しているつもりなのですが
なぜかファイルが生成されません
どこか、具合の悪いところはないでしょうか?
よろしくお願いします
gSzString04,05は変数が入っている

char title[1024]; // 初期化されている

        //    ファイルに出力
        sprintf( filename, "%s.txt", title );
        printf( " %s\n", filename );
        gSzString05.push_back( title );
        FILE    *filewt = fopen( filename, "wt" );
        if( filewt == NULL )
            printf( "error\n" );
        
        strcat( title, "\n" );
        fputs( title, filewt );
        int    j;
        for( j=0; j<gSzString04.size(); j++ )
        {
            memset( temp, 0, sizeof(temp) );
            sprintf( temp, "%s", gSzString04.at(j).c_str() );
            fputs( temp, filewt );
        }
        fclose( filewt );

Re:ファイルが作成されない

Posted: 2010年9月19日(日) 15:45
by へろりくしょん
何故かfopen()がNULLを返すということでしょうか。
それとも非NULLであるにもかかわらずファイルが存在しないということでしょうか。

前者なら変数 title にファイル名に使えない文字が含まれているとか、
ディレクトリの書き込み権限が無いとか、書き込み禁止(排他ロック含む)の同名のファイル名があるとかでしょうか。

後者なら、どこか変なパスに作ろうとしていませんか?
カレントディレクトリの確認をしてみては。

Re:ファイルが作成されない

Posted: 2010年9月19日(日) 16:14
by dic
>へろりさん
説明不足でした
fopenが非NULLを返しているのにファイルが新しく生成されないのです
ファイル名に問題があるのかも試しに title 変数に入っている文字列で
ファイルを手動で作って保存してみましたが、ファイルは作成できたので
ファイル名に問題はないはずなのです
fopen 直後の if( filewt == NULL )
のところでブレークポイントを設定し @err 変数を見てみましたが 0 が
入っていててエラーは発生してないのです

権限については全権限あるので問題ないです

Re:ファイルが作成されない

Posted: 2010年9月19日(日) 16:25
by シエル
FOPENの第二引数の"wt"ってあまり使ってるの見たことないんですが、
普通に"w"にしても駄目でしょうか?

Re:ファイルが作成されない

Posted: 2010年9月19日(日) 16:31
by へろりくしょん
パスは確認してみましたか?

どこか意図しないパスにファイルを作ってはいませんか。
fclose() 関数はちゃんと0を返しているでしょうか。
ループ内のバッファの初期化やファイル書き込み時にバッファオーバーラン等が発生してはいませんか。
その場合、ファイルポインタが破壊されている可能性も否定できません。

すべて正常に動作しているのでしたら、やっぱりパスぐらいしかちょっと思いつきませんね。

Re:ファイルが作成されない

Posted: 2010年9月19日(日) 17:27
by dic
>シエルさん
#include <stdio.h>

int main()
{
    FILE    *file;

    file = fopen( "hoge.txt", "wt" );
    fputs( "hoge\n日本語\n", file );
    fclose( file );

    file = fopen( "hoge2.txt", "w+t" );
    fputs( "hoge2\n日本語\n", file );
    fclose( file );

    file = fopen( "hoge3.txt", "w" );
    fputs( "hoge3\n日本語\n", file );
    fclose( file );

    return 0;
}
でそれぞれ wt, w+t, w の場合すべて試したのですがうまく動くようですが
へろりさんのおっしゃるとおり、どこかで変数がバッファーオーバーしてるかもしれないです
テストで、途中まで実行するのにそうとう時間かかるので、もうしばらく様子見します

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 04:04
by mila
fopen関数にファイルのフルパスを指定してみて
ファイルが作成されるかどうか確認してみてはいかがでしょうか。
例:fopen("C:\\hoge.txt", "w")

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 05:28
by dic
>milaさん
おっしゃるとおり GetCurrentDirectory で一応現在のディレクトリパスを追加してみました
しかし、問題は別にあったようです FILE *filewt = fopen( out, "w" ); の filewt の値が
変な値が入ってました
画像のように filewtの内容が0でファイルのポインタかどうかがわかってないかもしれないです
char    temp[1024];
    char    out[1024];
    char    dir[1024];
    GetCurrentDirectory( sizeof(dir), dir );

        memset( out, 0, sizeof(out) );
        sprintf( out, "%s\\%s.txt", dir, title );
        printf( " %s\n", out );
        gSzString05.push_back( title );
        FILE    *filewt = fopen( out, "w" );
        if( filewt == NULL )
            printf( "error\n" );
これはファイルのオープンに失敗しているということでしょうか?

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 07:42
by へろりくしょん
FILE構造体のメンバの詳細を理解していますか。

処理系が不明なので具体的な事は言えませんが、VisualStudio .NET 2003 では、ファイルオープン直後のファイルポインタの中身は、メンバ _flag、_file を除いてすべて0で初期化されていましたが、正常に動作しています。

FILE構造体の中身は処理系によって違いますし、その挙動(メンバの使われ方)もやっぱり違います。
そもそも、FILE型が構造体で無ければならないなんていう規格もありません。
ただ、FILE型は直接抽象宣言子で無ければならないとだけ定められています。

fopen() 関数はファイルのオープンに成功すると、ファイルオブジェクトへのポインタを返します。 失敗すればNULLを返します。
ですので、ファイル構造体の中身にかかわらず非NULLを返しているのであれば、成功しているのだと見なすべきです。

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 11:26
by ねこ
とりあえずまずここじゃないでしょうか

memset( temp, 0, sizeof(temp) );
sprintf( temp, "%s", gSzString04.at(j).c_str() );

多分vectorとstringクラスだと思いますが、tempのバッファを超えていないかチェックする処理を挟むか
「const char*」で受け取って使うなどして改善されないか。

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 15:13
by dic
>へろりさん ねこさん
FILE *filewt の中身は全部ゼロでよかったのですね
void    function011_141( char *filename, char *title )
{
    char    temp[1024];
    char    out[1024];
    char    dir[1024];
    GetCurrentDirectory( sizeof(dir), dir );

        memset( out, 0, sizeof(out) );
        sprintf( out, "%s\\%s.txt", dir, title );
        printf( " %s\n", out );
        gSzString05.push_back( title );
        FILE    *filewt = fopen( out, "w" );
●        if( filewt == NULL )
            printf( "error\n" );
        
        strcat( title, "\n" );
●        fputs( title, filewt );
        int    j;
        /*
        for( j=0; j<gSzString04.size(); j++ )
        {
            memset( temp, 0, sizeof(temp) );
//            sprintf( temp, "%s", gSzString04.at(j).c_str() );
            strcpy( temp, gSzString04.at(j).c_str() );
            printf( "%s", temp );
            fputs( temp, filewt );
        }
        */
●        fclose( filewt );
}
とコメントアウトしてみて実行してみたのですが
下の方のブレークポイントにいかずに処理されてしまってます
他のところのバグが影響している可能性があるのでしょうか?
●がブレークポイントで一番下のところに処理が流れてこない状態です

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 15:31
by dic
原因がわかりました
ファイル名に使っていけない文字が含まれてる場合に発生するようでした
半角(:)が含まれている場合このような困った処理をしていました
ひとまず、原因は分かりました

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 15:42
by dic
:(半角)を指定して fopen するとこのようなややこしいバグが入るようでした
環境も書いてませんでした すいません
Visual C++ 6.0 SP5 です

解決しました
ありがとうございました

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 16:23
by へろりくしょん
fclose() まで届かないというのが少々解せませんが。
以下は、fclose() がきっちり処理されたことを前提とします。

>ファイル名に使っていけない文字が含まれてる場合に発生するようでした
>半角(:)が含まれている場合このような困った処理をしていました

おそらく、ファイルは作られています。 それは fopen() 関数が 非NULL を返している事から明らかです。


>:(半角)を指定して fopen するとこのようなややこしいバグが入るようでした

エクスプローラからファイルが見えないということですので、ファイル名は:から始まっていませんか。


NTFSではドライブレターを除くファイル名に:が現れた場合、データストリームの指定を意味します。


ファイルを作ったはずであるパスへ移動し、dir /r のコマンドを打ってみてください。
ファイルが作られていることが確認出来るはずです。

Re:ファイルが作成されない

Posted: 2010年9月20日(月) 17:06
by dic
>へろりさん
dir コマンドで確認しました
ファイル名_ _(スペース)で作成されていました
内容は0バイトのファイルでした
メモ帳で開こうとしたら ファイルがありません新しくファイルを作成しますか?
とちょっとわからないエラーがでますね

本来だったら ファイル名_:_ほげほげ なんですが : のところがないですね
エクスプローラからも見れますが、削除できないです

Re:ファイルが作成されない

Posted: 2010年9月21日(火) 08:04
by へろりくしょん
>本来だったら ファイル名_:_ほげほげ なんですが : のところがないですね

dir /r と、rオプションをつけて見てください。


日付    ファイルサイズ      ファイル名(スペース)
      データストリームサイズ :データストリーム名(ほげほげ)

という出力が得られるはずです。

データストリームはあくまでもファイルオプションですから、いくらデータを書き込もうがファイルサイズに影響を与えません。
FILE *fp = fopen("hoge.txt:foo", "wt");
    fprintf(fp, "%s", "data string");
    fclose(fp);
というコードは、ファイル hoge.txt のデータストリーム foo に "data string" という文字列を書き込みます。

ファイルのメインストリームには一切書き込んでいませんので、ファイルサイズは0のままです。

Re:ファイルが作成されない

Posted: 2010年9月21日(火) 20:45
by dic
>へろりさん
データストリームとは初めて聞きました
色々セキュリティ関連のページが見つかりました
結構アングラっぽい情報ですね

情報は違う情報を出していました
WindowsXP Home NTFS でした

私に時間があり次第対処します
ありがとうございました
画像