안녕하세요. 천리안 프로그래머포럼 C++Builder 담당자 임펠리테리입니다.
만약 DataName이 크기가 정해지지 않은, 말 그대로 가변 길이를 가진다면,
예를 들어 길이가 최대값이 없이 임의의 길이가 된다면 구조체의 일부로 저장할
수 없습니다. 최대값으로 100이면 100, 200이면 200, 이런식으로 정해진 상태라면
char DataName[100]; 혹은 char DataName[200]; 이렇게 정의해주면 되지만,
가변적인 크기라고 해서 char *DataName; 혹은 char DataName[]; 이렇게
구조체를 정의했을 경우 문자열 자체가 저장되는 것이 아니라 문자열의 포인터가
저장됩니다.
만약 정말 가변적인 길이여야만 한다면 구조체의 멤버로서 저장할 수 없습니다.
sizeof(구조체이름) 을 해보면 마지막 인자가 포인터로서 포인터의 크기만큼만
계산되니까요.
그래서.. 가변적인 크기의 데이터를 저장하려면 구조체의 멤버로 넣으면 안되고,
따로 저장해주셔야 합니다.
따로 저장하는 경우에도, 읽을때 얼만큼 읽어야 할지 알수가 없으므로 길이를
먼저 저장한후, 그 다음에 가변데이터를 쓰면 됩니다.
읽을때는 앞부분에 먼저 저장된 '길이' 부분을 읽어서 얼만큼 읽어야 할지를
정한후 그만큼 읽어오면 되죠.
길이를 확실히 하기 위해 이 멤버를 쓰기 전에 스트링의 길이를 먼저 저장
하는 겁니다.
만약 TFileStream을 이용해서 읽고 쓴다면,
쓸때는...
TFileStream pFile = new TFileStream(화일이름, fmOpenWrite);
... (딴거 열심히 쓰고...)
pFile->Wrtie(MyStruct1, sizeof(MyStruct));
int DataNameLen = strlen(MyStruct1->DataName) + 1;
pFile->Write(&DataNameLen, sizeof(int));
pFile->Write(MyStruct1->DataName, DataNameLen);
... (나머지도 계속 열심히 쓰고...)
delete pFile;
그리고 이걸 읽어올때는..
TFileStream pFile = new TFileStream(화일이름, fmOpenRead);
.... (딴거 열심히 읽고...)
pFile->Read(MyStruct1, sizeof(MyStruct));
int DataNameLen;
pFile->Read(&DataNameLen, sizeof(int));
pFile->Read(MyStruct1->DataName, DataNameLen);
... (나머지도 계속 열심히 읽고...)
delete pFile;
이런식으로 하면 됩니다. 물론 MyStruct1은 MyStruct *형 객체입니다.
만약 fopen과 같은 전통적인 스트림 입출력함수나 open과 같은 핸들계열 입출력
함수를 쓰셨더라도 비슷하게 하시면 됩니다. 코드는 비슷해지죠.
이렇게 세팅해준 후에 저저장해준다면 데이터의 길이에 관계없이 저장하고 읽어올
수 있습니다.
잘시간에 잠을 못자고 계속 버그만 잡고 있다가 답변하려니 제대로 한건지
모르겠네요. 혹시 잘 안되면 다시 질문 올려주시기 바랍니다.
그럼 이만... 에구 졸린다...
독립문에서 임펠리테리였습니다.
(cbuilder, cbuilder@thrunet.com)
|