2010-04-07 4 views
3

여기서 변수와 데이터 구조이다이진 파일에 편지를 쓰시겠습니까?

struct Part_record 
{ 
    char id_no[3]; 
    int qoh; 
    string desc; 
    double price: 
}; 
--- 
(Using "cin" to input data) 
--- 
Part_record null_part = {" ", 0,"       ",0.0}; 
--- 
--- 
file.seekg(-(long)sizeof(Part_record), ios::cur); 
file.write((char *)&part, sizeof(Part_record)); 

세 변수 QOH, Id_no & 가격, 올바르게 작성하지만, "DESC" 변수 옳지 않다. Part_record를 다른 방법으로 초기화해야합니까? 길이는 20 자 여야합니다.

충분한 정보가 여기있는 경우 조언을 공유하십시오.

답변

3

std::string은 구조가 Part_record이 아닌 동적으로 할당 된 메모리에 데이터를 보관합니다.

0

데이터가 쓰여지지 않습니다. string은 고정 크기가 아닌 동적 클래스이므로 (기술적으로는 고정 크기이지만 동적으로 확장 가능한 문자 배열에 대한 포인터가 포함되어 있기 때문에) char[20]을 대신 사용해야합니다.

내가 char[20]라고 말한 이유는 문자열이 20 자라고 말했기 때문입니다. 그러나 종료 널 바이트에 대해 추가 문자를 포함시켜야합니다. 또한 예제에는 25 개의 공백이 포함 된 문자열이 포함되어 있으므로이 경우 char[26]이 필요합니다.

모든 크기의 문자열이 있고 최대 크기를 모르는 경우 구조체에 모든 데이터를 가지고있는 것보다 더 복잡한 작업을 수행해야합니다.

+1

포스터는 전체 구조로 I/O 블록을 사용하지 않고 각 요소를 개별적으로 읽고 써야합니다. 블록 I/O에는 많은 구멍이 있으며'std :: string'을 가진 필드가 그 중 하나입니다. 더 빠른 I/O를 위해서, 구조체의 멤버는 연속적으로 버퍼에 복사 될 수 있고 버퍼는 하나의 블록으로 쓰여질 수 있습니다.OP 디자인의 또 다른 단점은 컴파일이 필드 사이에 패딩을 삽입 할 수 있다는 것입니다. –

0

std::string에는 실제 문자 데이터에 대한 포인터가 들어 있으며, 원시 구조, 즉 포인터를 직렬화합니다.

(즉 문자열의 데이터의 PTR와 길이를 얻을 수 desc.data()desc.size()를 사용합니다.) 문자열에 대한 특별한 처리와 별도로 각 변수를 쓰기 당신은 STL 중 하나를 std::string 객체 쓰기 (또는 수 없습니다

1

컨테이너)를 파일에 저장합니다. 동적으로 할당 된 데이터에 대한 내부 포인터를 포함합니다. 문자열의 내용 대신 포인터 주소를 파일에 쓰는 것을 끝낼 것입니다.

std::string 데이터를 파일로 작성해야하는 경우 iostream 라이브러리를 사용하는 것이 좋습니다. 그 실패, 당신은 당신이 시도하고있는 것과 유사한 무언가를 달성하기 위해 [0] part.desc 직접 문자 데이터에 액세스 할 수 있습니다

fwrite(&part.desc[0], part.desc.size()); 
0

이 출력 스트림에 개별 구성원을 작성하거나 구조를 가지고 이렇게 또는 버퍼에 개별 구성원을 쓰기 :

struct Part_record 
{ 
    char id_no[3]; 
    int qoh; 
    string desc; 
    double price: 
// Block I/O methods 
    size_t Size_On_Stream(void) const 
    { 
     size_t size = 0; 
     size = sizeof(id_no) + sizeof(goh) + sizeof(price); 
     size += descr.length() + 1; // +1 for terminating null character 
     return size; 
    } 
    void Store_To_Buffer(unsigned char *& p_buffer) const 
    { 
     std::copy((unsigned char *)&id_no[0], (unsigned char *)&id_no[3], p_buffer); 
     p_buffer += sizeof(id_no); 
     std::copy((unsigned char *)&goh, (unsigned char *)(&goh) + sizeof(goh), p_buffer); 
     p_buffer += sizeof(goh); 
     std::copy((unsigned char *)&price, (unsigned char *)(&price) + sizeof(price), p_buffer); 
     p_buffer += sizeof(price); 
     strcpy(p_buffer, descr.str()); 
     p_buffer += descr.length(); 
     *p_buffer = 0x00; 
     ++p_buffer; 
     return; 
    } 
    void Write_To_Stream(ostream& output) const 
    { 
     size_t buffer_size = Size_On_Stream(); 
     unsigned char * buffer = new unsigned char [buffer_size]; 
     unsigned char * p_buffer = buffer; 
     Store_To_Buffer(p_buffer); 
     output.write((char *)buffer, buffer_size); 
     delete [] buffer; 
     return; 
     } 
}; 

당신이 소수점 값, 정수 값 및 텍스트 부동 한 이후, 나는 매우 당신은 CSV 또는 XML과 같은 ASCII 또는 텍스트 기반 형식을 사용하는 것이 좋습니다. 이진 버전의 수 (정수 및 부동 소수점)는 OS 버전 또는 컴파일러 버전간에 플랫폼간에 호환되지 않을 수 있습니다. 또한 가변 길이 텍스트는 바이너리 형식으로 처리해야하는 고통입니다.

관련 문제