2017-12-20 6 views
3

나는이 질문과 비슷한 질문을 보았습니다. 그러나이 모든 시도는 제 경우에는 효과가 없습니다. 세 가지 다른 정수 값을 가진 클래스를 이진 파일에 저장하려고합니다. C++ 스트림 과부하에 대해이 문제를 해결해야합니다. 연산자 "< <"/ ">>". 그래서 내 실제 코드 내 파일에서 바이너리로 정수 값을 저장하는 것하지만 내 이진 파일에서 그들을 다시로드하려고하면 단지 원래 값과 같은 아닌 정수 값을 반환합니다.
나의 등급 :정수 값을 가진 클래스를 스트림 연산자로 이진 파일로 저장 >>/<<

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

}; 

내 방법은 파일에 단일 값을 저장합니다. 나는 reinterpret_cast이 하나를 시도하지 않고, 예를 들면 : (숯불 *)이 대한 결과 기능을 테스트하려면 코드 $ 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; 
} 

은 1,878,006,928 입니다 :

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을 수정하면 있기 때문에 매우 위험하다

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

당신이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

관련 문제