2012-04-01 1 views
1

int와 간단한 구조체 같은 다양한 값을 이진 파일로 내보내려고합니다. 다음은 몇 가지 코드입니다.ostream :: write가 전체 struct를 쓰지 않습니까?

#include &ltiostream> 
#include &ltfstream> 
#include &ltcstdint> 
using namespace std; 

template&ltclass T> void writeToStream(ostream& o, T& val) 
{ 
    o.write((char*)&val, sizeof(T)); 
    cout << o.tellp() << endl; //always outputs 4 
} 

struct foo { 
    uint16_t a, b; 
}; 

int main() 
{ 
    foo myFoo = {42, 42}; 
    ofstream test("test.txt", ios::binary); 
    writeToStream(test, myFoo); 
    test.close(); 
}

프로그램에서 4 바이트 길이의 출력 파일을 생성해야합니다. 그러나 그것을 열면 2 바이트 밖에되지 않습니다. myFoo.amyFoo.b을 256 이상의 값으로 설정하면 (저장하는 데 1 바이트 이상 필요) 파일의 길이가 4 바이트가됩니다. Win7에서 Visual Studio 11 Developer Preview를 사용하고 있습니다. 다른 시스템이나 컴파일러에서 같은 일이 발생하는지 확인하지 않았습니다. 256 이하의 a 또는 b 값에 ​​대해 올바르게 출력하려면 어떻게해야합니까?

+0

파일 길이는 어떻게 결정됩니까? –

+0

글쎄, 메모장에서 열어서 ++, 그리고 그것을 256 미만의 값을 2 문자로 표시, 그렇지 않으면 4. 그러나, 나는 파일을 오른쪽 클릭하고 "속성"을 클릭하면 4 바이트를 표시합니다 ... – Mark

+3

나는 그 안에 문제가 있다고 생각합니다. 텍스트 편집기에서 이진 파일 크기를 확인하여 이진 파일 크기를 확인하려고합니다. –

답변

2

파일은 저장된 형식을 인식하는 프로그램에서만 읽을 수 있습니다. 메모장 + +는 파일이 저장된 형식에 대한 이해가 없으므로 다시 읽을 수없고 현명하게 렌더링 할 수 없습니다. ASCII 텍스트와 같은 Notepad ++ 형식으로 파일을 작성하거나 작성한 형식을 이해하는 프로그램으로 파일을 읽으십시오.

+0

또는 파일 브라우저 또는 터미널 명령을 사용하여 파일 크기를 결정하십시오 ... – Potatoswatter

+0

메모장 ++에서 대개 널 문자와 그 종류의 것들을 보여주기 때문에 나는 던져 졌다고 생각합니다. 그러나 16 진수 편집기를 사용하여 Notepad ++가 잘못되었음을 확인했습니다. – Mark

0

다음과 같이 코드를 정리했습니다. 왜 오래된 코드가 2 바이트를 출력하는지 모르겠지만 새로운 코드는 4를 출력합니다.

#include <iostream> 
#include <fstream> 
#include <cstdint> 
using std::cout; 
using std::endl; 
using std::uint16_t; 
using std::ostream; 
using std::ofstream; 
using std::ios; 

template <class T> void writeToStream(ostream& o, T& val) 
{ 
    o.write(reinterpret_cast<char *>(&val), sizeof(T)); 
    cout << o.tellp() << endl; //always outputs 4 
} 

struct foo { 
    uint16_t a, b; 
}; 

int main() 
{ 
    foo myFoo = {42, 42}; 
    ofstream test("test.txt", ios::binary); 
    writeToStream(test, myFoo); 
    // Just let the stream "test" pass out of scope. 
    // It closes automatically. 
    //test.close(); 
    return 0; 
} 

는 (내 표준 라이브러리 cstdint, 그래서 난 오히려 uint16_t,보다 short을 사용 부족하지만, 나는이 문제를 의심하십시오.) std::ofstream 유형 std::ostream에서 파생

. writeToStream() 함수는 일반화 된 경우 std::ostream을 전달하면 더 행복하거나 더 규칙적이고 더 일반적입니다. 또한, 정보 : using namespace std;을 발행하는 것이 C++에서는 거의 권장되지 않습니다.

행운을 빈다.

+1

당신의 프로그램은 그의 프로그램과 동일하고, 이미 효과가 있기 때문에 효과가있는 것으로 보입니다. – Potatoswatter