2016-04-29 5 views
0

を作成+読んで私がしたい:それが存在しない場合は作成するCのfopenのモードでは、書き込み+は

  1. ファイル、not overwritten if it doesを。 " "W +"、 "RW" "RWB +" "R + B"" W + B - 読み取りと書き込みとfseek私は

をしたい今までどこで、私は、有効なモードを見つけることができないために

  • "a +"または何ですか?

    int fd =open("fname", O_RDWR | O_CREAT, 0666); 
    

    が、私はfopen alternative知りたい:

    も行い、基本的なレベルの 'openは' です。 私が試したすべてのモード文字[w、r、a、+]の組み合わせは、内容を上書きするか、fseek-fwriteがどこに書き込むべきかを書き留めません。 "a +"は常にfseekが何を設定しても追加されます... "rw +"は正常に動作しますが、存在しないファイルを作成しません。

    更新:なぜ、たとえば明確にするために、 "+" は解決策ではありません:

    #include <stdio.h> 
    int main() 
    { FILE *fp =fopen("aaa.txt", "a+"); 
        fwrite("aaaaaaaaaaaaaaaaaaa", 1, 10, fp); 
        fseek(fp, 5, SEEK_SET); 
        fwrite("AAA", 1, 3, fp); 
        fclose(fp); 
        return 0; 
    } 
    runned with: $ rm aaa.txt; gcc test.c && ./a.out && cat aaa.txt && echo . 
    produces wrong result: aaaaaaaaaaAAA. 
        result should be: aaaaaAAAaa 
    

    アップデート2:私はで終わる要約...最低限の機能:

    FILE *fopenrwc(char*n) {FILE*f=fopen(n,"a");if(f)fclose(f),f=fopen(n,"r+");return f;} 
    or: 
    FILE *fopenrwc(char*n) {return fdopen(open(n,O_RDWR|O_CREAT,0666),"r+");} 
    
  • +1

    なぜ 'a +'はあなたのためのスイートではありませんでしたか? –

    +0

    「a +」が機能しない理由を明確にしてください。 – Leandros

    +0

    @SouravGhosh "a +"は私の最初の選択でしたが、内容のあるファイルでは、fseek(0)、write(buf)...ファイルの最後に追加するのではなく最後に追加します。それはfseekとftellが何を言っているかをマザーに付加していない。 – MetNP

    答えて

    2

    fopen()のマニュアルページを参照すると、標準のオープンモード文字列のいずれも要件を満たしていません。

    あなたがopen()を使用することができるように十分にPOSIXのようなマシンにしている場合は、あなたが示したオプションでopen()を使用することを可能にしてから使用するように、ファイルストリームを作成しますfdopen()のメリットを過小評価してはいけません。そのファイル。

    "rw+"は有効なモードではありません。あなたが運が良ければ、r+と扱われます。

    あなたには、いくつかの理由でfdopen()を使用できない場合、あなたはr+をしようとしてオフし、それがw+を使用して失敗した場合に最高であってもよく、小さな脆弱性のウィンドウが開き、誰かがファイルを作成してw+オプションで壊れてしまったり、シンボリックリンクを作成したりして、意図していないファイルを作成することになります。

    これは、以前はopen()で作業する必要があった方法です。もともと、あなたはopen()と呼ばれました。前日にO_CREATがありましたが、それが失敗した場合は、代わりにcreat()を使用しました。それはずっと前ですが、7th Edition UNIX Programmer's Manual Vol 2の「UNIXプログラミング」を参照してください。

    通常、access()でテストすることは役に立ちません。TOCTOU - チェックの時間、使用時間 - access()open()(またはfopen())の使用の間にギャップがあるため、脆弱性の脆弱性が残っています。また、open()creat()の問題、またはfopen()の2つの問題があります。その後、umask()によって修正されますが、細かいコントロール、などO_EXCL、またはそのようなさえO_DSYNCO_NOCTTY、またはデフォルト以外の作成されたファイルのパーミッションを制御などの特殊な性質をしたい場合は

    open()プラスfdopen()は事実です行く唯一の方法。

    3

    なしあり簡単なfopenであなたの要件を満たす直接的な方法。私見、あなた最良の選択は、最初のファイルを作成するために、低レベルopenを使用して、すべてのCライブラリIO関数で使用することができますFILE *を取得するには(ジョナサン・レフラーにより示唆されるように)fdopenを使用することです:

    int fd =open("fname", O_RDWR | O_CREAT, 0666); 
    FILE *fp = fdopen(fd, "r+"); 
    /* Ok, you can do what you want with fp */ 
    
    関連する問題