2017-12-20 33 views
3

私はおそらくかなり簡単な質問をしています。私はすでにこのような類似の質問を見ましたが、試したすべてが私の場合は機能しません。私は3つの異なる整数値を持つクラスをバイナリファイルに保存しようとしています。 C++ストリームの演算子 "< <"/">>"のオーバーロードについてこれを解決する必要があります。だから私の実際のコードは、私のファイルにバイナリとして整数値を保存するようだが、バイナリファイルからそれらをロードしようとすると、元の値と同じではない整数値が返されます。
私のクラス:整数値を持つクラスをストリームオペレータでバイナリファイルに保存する>>/<<

class Time{ 
public: 
    int hour; 
    int minute; 
    int second; 

}; 

私のメソッドは、ファイルへの単一の値を保存します。私はreinterpret_castはであり、例えばなしで、このいずれかを試してみました:(のchar *)$ time.hour

std::ostream& operator<<(std::ostream &os, Time &time){ 

    os.write(reinterpret_cast<const char *>(&time.hour),sizeof(int)); 
    os.write(reinterpret_cast<const char *>(&time.minute),sizeof(int)); 
    os.write(reinterpret_cast<const char *>(&time.second),sizeof(int)); 
    return os; 
} 

std::istream& operator >>(std::istream &is,Time &time){ 

    is.read((char*)&time.hour,sizeof(int)); 
    is.read((char*)&time.minute,sizeof(int)); 
    is.read((char*)&time.second,sizeof(int)); 
    return is; 
} 

マイコードこのため、結果に機能をテストするために1878006928 です:

int main() { 
    Time time; 
    time.hour = 24; 
    time.minute = 33; 
    time.second = 10; 
    std::ofstream os("test.txt", std::ios::binary | std::ios::out); 
    os << time; 
    Time time2; 
    std::ifstream is("test.txt",std::ios::binary | std::ios::in); 
    is >> time2; 
    std::cout << time2.hour; 

} 

あなたを願っています私の問題を理解することができます。

+1

'書き込み操作後にos.flush()を呼び出します。 – ivaigult

答えて

0

@ivaigultに気づいたように、std::flushofstreamに忘れました。 私の答えを完成させるためにコードにいくつかのコメントを書きました。 >sizeof(new type) - あなたのTimetime.hourを変更する場合にもsizeof(int)を変更するを覚えておく必要があるためこれは非常に危険です

os.write(reinterpret_cast<const char *>(&time.hour),sizeof(int)); 

:最も重要なこと私見のようなものを書くことを避けるためです。後で発見するのが面白くないメモリ破損のバグがあるのを忘れると! C++ 11あなたはdecltype(time.hour)を使用することができますと、これは与える:のような:ここではさらに、アドゥ修正作業C++のコメントと11のコードでなければ

os.write(reinterpret_cast<const char *>(&time.hour), sizeof(decltype(time.hour))); 

:あなたが忘れているようだ

#include <fstream> 
#include <iostream> 

class Time 
{ 
public: 
    int hour; 
    int minute; 
    int second; 

    // *** would allow you to access protected members (if any) 
    // 
    friend std::ostream &operator<<(std::ostream &os, Time &time); 
    friend std::istream &operator>>(std::istream &is, Time &time); 
}; 

std::ostream &operator<<(std::ostream &os, Time &time) 
{ 

    // *** sizeof(in) -> sizeof(decltype(time.hour) 
    // otherwise bug prone: if you modify the Time class, you have to remember to 
    //      modify this function too! 
    os.write(reinterpret_cast<const char *>(&time.hour), sizeof(decltype(time.hour))); 
    os.write(reinterpret_cast<const char *>(&time.minute), sizeof(decltype(time.minute))); 
    os.write(reinterpret_cast<const char *>(&time.second), sizeof(decltype(time.second))); 
    return os; 
} 

std::istream &operator>>(std::istream &is, Time &time) 
{ 

    // *** ditto: bug prone 
    // + be consistent: if you use reinterpret_cast before, use it also here 
    // and not the C-style cast(char *) 
    is.read(reinterpret_cast<char *>(&time.hour), sizeof(decltype(time.hour))); 
    is.read(reinterpret_cast<char *>(&time.minute), sizeof(decltype(time.minute))); 
    is.read(reinterpret_cast<char *>(&time.second), sizeof(decltype(time.second))); 
    return is; 
} 

int main() 
{ 
    Time time; 
    time.hour = 24; 
    time.minute = 33; 
    time.second = 10; 

    // *** std::ios::binary is enough, std::ios::out is redundant with 
    //  std::_o_fstream 
    std::ofstream os("test.txt", std::ios::binary); 
    os << time; 

    // os.close(); or at least a flush 
    os.flush(); 

    Time time2; 
    // *** ditto: std::ios::binary is enough 
    std::ifstream is("test.txt", std::ios::binary); 
    is >> time2; 
    std::cout << time2.hour << " " << time2.minute << " " << time2.second; 
} 
+1

ありがとうございました。そしてコメントのために。私はバッファがストリームの最後の使用の後に常に洗い流されると思った...心配しないで – Retrogott

関連する問題

 関連する問題