0

学校のプロジェクト用に、多くのバイナリ ファイルを含む C++ プログラムを作成しています。私の問題は、コンパイラが書き込みステートメントに遭遇するたびに (これは、fstream::write を使用してクラスのオブジェクトからバイナリ ファイルにデータを書き込むことを意味します)、実行が停止し、異常終了メッセージが表示されることです。次のステートメントは実行されませんが、前のすべてのステートメントが実行されるため、「書き込み」ステートメントが問題であると確信しています。代わりに fwrite を使用すると問題は解決したように見えましたが、実際にはデータがファイルに書き込まれていないことがわかりました。別の関数または「this」ポインターを使用するメソッドでオブジェクトをファイルに書き込もうとしましたが、コンピューターはそれを受け入れないようです。

プログラムは数日前まで問題なく動作していましたが、突然動作しなくなったようです。問題は 5000 行を超えるプログラム全体に広がっているため、ソース コードを添付できません。ただし、問題の原因の例を次に示します。

bottle b; //bottle is a class
fstream file ("Bottle.dat",ios::out|ios::binary);
file.write ((char*)&b,sizeof(b));

代替として、私も試しました

FILE*fptr=fopen ("Bottle.dat","w");
fwrite (&b, sizeof(b), 1, fptr);

前者は異常終了、後者は動作しません。コンパイル中にエラー メッセージは表示されません。誰でも私を助けることができますか?私はプログラミングのまったくの初心者ですが (まだ高校生です)、シンプルに保つようにしてください。ありがとう!

編集:おそらくこれはより良い例として機能します。

class irrigation
{   int n,i,itime[20],t[20];
    float amt[20],water[20];
protected:
    float irr;
public:
    float getirr()
    {   return irr;
    }
    void irrigate();
};

void irrigate_calc()
{   fstream file ("Irrigate.dat",ios::in|ios::binary);
    irrigation i;
    file.read ((char*)&i,sizeof(i));
    file.close();
    i.irrigate();
    fstream file1 ("Irrigate.dat",ios::out|ios::binary);
    file1.write ((char*)&i,sizeof(i));
    file1.close();
}

私が知る限り、ファイルを読み取り用に開き、もう一度閉じてから書き込み用に開くと、問題が発生します。もちろん、ios::in、ios::out、および ios::ate モードで一緒にファイルを直接開いてみましたが、それは大変なことでした。

編集 2: 同じプログラムが直面しているもう 1 つの問題は、一部の通常の cout ステートメントが断続的にゴミを吐き出すことです。多くの特殊文字と、まったく関係のない他の cout ステートメントからの小さなビットです。これが起こっている特定の理由はありますか?

4

1 に答える 1

1

オブジェクトはそうではないのでPOD、簡単な方法で、そのすべてのメンバーを書き出すことを試みることができます。例えば、

#include <fstream>

using namespace std;

class B
{
public:
    // Simple constructor
    B(int mem1, char mem2) : member1(mem1), member2(mem2) {}

    // Have some methods here
    bool write() const {
      fstream file("Bottle.dat", ios::out|ios::binary);
      if(!file.is_open())
        return false;
      file.write(reinterpret_cast<const char*>(&member1), sizeof(int));
      file.write(&member2, sizeof(char));
      file.close();
      return true;
    }

private:
    int member1;
    char member2;
};

int main()
{
  B sample(52, 'c');
  sample.write();
  return 0;
}

これで、電話yourobj.write()をかけて、に書き出すことができますBottle.dat。あなたはあなたが望むとにかくあなたのデータを書き出す/エンコードすることができます。しかし、これは単純な直接出力です。最初の4バイト(まあ、sizeof(int)バイト)はにmember1なり、次のバイトはになりますmember2。したがって、必要に応じて、この形式で簡単に読むことができます。

編集

コードを更新して、コンパイル可能なサンプルにしました。16進エディターで出力ファイルを観察して、すべてが正しいことを確認できます。charに対応する('c')を視覚的に確認できるようにする必要があります(どのエディターでも)member2。これを16進エディタで開くと、最初の4バイトが数値に等しいことがわかります0x34。マシンのエンディアンに応じて、次のように見える00000034か、34000000これは10進数52であり、これは私のサンプルコードに基づいて予想されるものです。

于 2013-01-06T02:13:30.123 に答える