バグ : ファイルを上書きする

Posted: 2012年03月23日

ファイルを上書きするプログラムでよく書いてしまうバグを紹介します。

プログラムプログラム:

 #include  <stdio.h>

 int main(int argc, char *argv[])
 {
    std::ofstream ostream(argv[1], std::ios::out);
    if (ostream.fail() == true) {
        // ファイルのオープンに失敗
        return -1;
    }

    // 書き込み処理
    for (int nIndex = 1; nIndex < argc; nIndex++) {
        ostream.write(argv[nIndex], strlen(argv[nIndex]));
    }

    ostream.close();

    return 0;
 }

このプログラムにどのようなファイル操作関連のバグがあると思いますか?

  • ファイルの内容を削除していないため、1から出力する場合は、前のデータが残る場合がある。
  • データを連結する場合は、「std::ios::app」のフラグを指定していないため、write時には、先頭に出力される。

ファイルの全データを書き込む場合

改善版プログラム改善版プログラム:

 #include  <stdio.h>

 int main(int argc, char *argv[])
 {
    std::ofstream ostream(argv[1], std::ios::out | , std::ios::trunc);
    if (ostream.fail() == true) {
        // ファイルのオープンに失敗
        return -1;
    }

    // 書き込み処理
    for (int nIndex = 1; nIndex < argc; nIndex++) {
        ostream.write(argv[nIndex], strlen(argv[nIndex]) + 1);
    }

    // 実際にファイルに書きこむ
    ostream.flush();
    if (ostream.bad() == true) {
        // ファイル書き込みに失敗
        return -1;
    }

    ostream.close();

    return 0;
 }

解説解説:

std::ios::truncを指定することでファイルを開いたときに、以前のデータをクリアします。

ファイルの末端にデータを追記する場合

改善版プログラム改善版プログラム:

 #include  &lt;stdio.h&gt;

int main(int argc, char *argv[])
 {
    std::ofstream ostream(argv[1], std::ios::out | std::ios::app);
    if (ostream.fail() == true) {
        // ファイルのオープンに失敗
        return -1;
    }

<pre><code>// 書き込み処理
for (int nIndex = 1; nIndex &amp;lt; argc; nIndex++) {
    ostream.write(argv[nIndex], strlen(argv[nIndex]) + 1);
}

// 実際にファイルに書きこむ
ostream.flush();
if (ostream.bad() == true) {
    // ファイル書き込みに失敗
    return -1;
}

ostream.close();

return 0;
</code></pre>

}

解説解説:

std::ios::appを指定することで、ファイルを開いたときに、末端に出力できるようになります。
 (ファイルポインターを末端に移動してくれます。)
この他にも、

ostream.seekp( 0, std::ios::end );
で出力先を末端に移動することができます。

ファイルを開くときのフラグは以下種類があります。

フラグ 説明
in ファイルを読み込みモードで開きます
out ファイルを書きこみモードで開きます 
app ファイルを追記モードで開きます
ate ファイルの開いたときに、ファイルポインターを末端に移動します
trunc ファイルを開いたときに、ファイルの内容をクリアします
binary コントロールコードなど変換しません
カテゴリー: バグ, プログラム | タグ: , , | コメント無し »

コメント