Q&A

  • 바이너리 데이타를 읽는 소서인데 잘 안되서 글을 올립니다.
C Source를 Delphi로 전환 하는데 결과값이 이상하게 나옵니다. 뭐가 잘못 되었는지 모르겠습니다.
여러 유저님들의 많은 가르침 부탁 드립니다.

첨부 파일에 해당 바이너리 데이타를 첨부 합니다.

-------------------------Delphi Source---------------------------
<!--CodeS-->
var
  filestream : TFileStream;
  TempChar : array [0..256] of char;
  wdata : array [0..256] of WCHAR;
  i,k,l,m : integer;
begin
  FileStream:= TFileStream.Create('dcode.cm', fmOpenRead);
  while true do
  begin
    try
      i := i + 1;
      FileStream.ReadBuffer(TempChar, 256);
      FileStream.Seek(soFromCurrent,1);
    except
      break;
    end;
      MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PChar(@TempChar), -1, PWideChar(@wData), 256);

    memo1.Lines.Add(wdata);
  end;
  FileStream.Free;

<!--CodeE-->

----------------------------결 과---------------------------------------------


嬖紙

종로3가
疵?가






t'

산동5가

/

'
"$,

"?
-----------------------------------------------------------------------------------
---------------------------------C Source--------------------------------------
C Source

<!--CodeS-->
BOOL CCMContainerView::LoadDCodeInfo()
{
        CFile fileDCode;
        if(!fileDCode.Open(DCODE_INFO_FILENAME, CFile::modeRead))
                return FALSE;

        // 파일로부터 정보를 읽어온다.
        ClearDCodeInfo();

        // DCode1의 개수
        int nCode1Num;
        fileDCode.Read(&nCode1Num, sizeof(int));
        for(int i = 0; i < nCode1Num; i++)
        {
                SDCode1* pCode1 = new SDCode1;
                // DCode1의 Name
                ReadString(&fileDCode, pCode1->strName);
                // DCode1에 속해있는 DCode2의 개수
                int nCode2Num;
                fileDCode.Read(&nCode2Num, sizeof(int));
                for(int j = 0; j < nCode2Num; j++)
                {
                        SDCode2* pCode2 = new SDCode2;
                        // DCode2의 Name
                        ReadString(&fileDCode, pCode2->strName);
                        // DCode2에 속해있는 DCode3의 개수
                        int nCode3Num;
                        fileDCode.Read(&nCode3Num, sizeof(int));
                        for(int k = 0; k < nCode3Num; k++)
                        {
                                SDCode3* pCode3 = new SDCode3;
                                // DCode3의 Code
                                fileDCode.Read(&pCode3->cCode1, sizeof(char));
                                if((int)pCode3->cCode1 != 0)
                                {
                                        fileDCode.Read(&pCode3->iCode2, sizeof(short));
                                        fileDCode.Read(&pCode3->nCode3, sizeof(int));
                                }
                                else
                                {
                                        pCode3->iCode2 = 0;
                                        pCode3->nCode3 = 0;
                                }
                                // DCode3의 Name
                                ReadString(&fileDCode, pCode3->strName);
                                // DCode3에 속해있는 DCode4의 개수
                                int nCode4Num;
                                fileDCode.Read(&nCode4Num, sizeof(int));
                                for(int l = 0; l < nCode4Num; l++)
                                {
                                        SDCode4* pCode4 = new SDCode4;
                                        // DCode4의 Code
                                        fileDCode.Read(&pCode4->cCode1, sizeof(char));
                                        fileDCode.Read(&pCode4->iCode2, sizeof(short));
                                        fileDCode.Read(&pCode4->nCode3, sizeof(int));
                                        // DCode4의 Name
                                        ReadString(&fileDCode, pCode4->strName);

                                        pCode3->sCode4List.Add(pCode4);
                                }
                                pCode2->sCode3List.Add(pCode3);
                        }
                        pCode1->sCode2List.Add(pCode2);
                }
                m_sDCodeList.Add(pCode1);
        }

        fileDCode.Close();

        m_bLoadedDCode = TRUE;
        return TRUE;
}


void CCMContainerView::ReadString(CFile* pFile, CString& strItem)
{
        int nLength;
        char cLength;        
        char szTemp[256];

        pFile->Read(&cLength, sizeof(char));
        nLength = (int)cLength;
        if(nLength == 0)
                strItem.Empty();
        else
        {
                pFile->Read(szTemp, sizeof(char) * nLength);
                szTemp[nLength] = '\0';
#ifdef _UNICODE
                WCHAR szwcBuffer[256];
                // 2005/06/14 by Shaqlee
//                MultiByteToWideChar(CP_ACP, 0, szTemp, strlen(szTemp), szwcBuffer, 256);
                MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTemp, nLength+1, szwcBuffer, 256);
                strItem.Format(_T("%s"), szwcBuffer);
#else
                strItem.Format(_T("%s"), szTemp);
#endif
        }
}

void CCMContainerView::WriteString(CFile* pFile, CString strItem)
{
        int nLength = strItem.GetLength();
        char cLength = (char)nLength;

        pFile->Write(&cLength, sizeof(char));
        if(nLength != 0)
        {
#ifdef _UNICODE
                char szTemp[256];
                // 2005/06/14 by Shaqlee
//                WideCharToMultiByte(CP_ACP, 0, strItem, strItem.GetLength(), szTemp, 256, NULL, NULL);
                WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, strItem, strItem.GetLength(), szTemp, 256, NULL, NULL);
                szTemp[strItem.GetLength()] = '\0';
                pFile->Write(szTemp, strlen(szTemp));
#else
                pFile->Write(strItem.GetBuffer(strItem.GetLength()), sizeof(char) * nLength);
#endif
        }
}

<!--CodeE>
1  COMMENTS
  • Profile
    오매가 2008.02.13 20:39
    초보자가 요즘 Unicode와 관련된 프로그램을 만들고 있는데, 내가 알려고 하는 것과 비슷한것 같아서...

    아래와 같이 메모리스트림으로 읽어들였는데 이상은 없는것 같은데요.
    MultiByteToWideChar API는 뭐하는건지 모르겠어요.
    wData는 왜 메모장에 뿌리려고 하는건지? wData는 Unicode인것 같은데....
    TntRichEdit를 사용해 보시는것이 좋을듯 합니다.

    var UniMStream: TMemoryStream;

    procedure TMainForm.FormCreate(Sender: TObject);
    var fName: string;
    begin
      UniMStream:=TMemoryStream.Create;
      stream:=NIL;
      try
        fName:='dcode.cm';
        stream:=TFileStream.Create(fName,fmOpenRead);
        UniFStream.loadfromstream(stream);
        UpdateIMG;
      finally
        stream.free;
      end;
    end;

    procedure TMainForm.FormDestroy(Sender: TObject);
    begin
      UniMStream.free;
    end;