C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[55227] Re:AnsiString 와 char * 비교 부탁드립니다.
장성호 [nasilso] 2194 읽음    2008-11-21 13:18
요거는 저도 정확히 모르는 어려운 문제네요

빌더의 VCL에 델파이(Object-pascal)로 만들어져 있는것 이시죠?

델파이 컴파일러에서는 String이 int 나 word 처럼   컴파일 기본형입니다.

그런데 C++빌더에선느 String이 컴파일기본형이 아니라 AnsiString이라는 클래스로 구현되어있습니다.

델파이의 String과 빌더의 AisiString클래스와 어떻게 맞추었는지 참 신기한데....

여튼 그사에에서 나는 문제 같습니다.

보통
Delphi의 string에서 c++빌더의 AnsiString으로 받는것은 문제없던데

Edit의 Text변수는 AisiString형이기는 하지만 그냥 변수가 아니라 property입니다.

즉 Edit->Text를 접근하면 그때 VCL의 Controls유닛에 있는 GetText라는 함수가 호출되고
거 함수안에서 버퍼를 확보하고 test의 내용을 복사합니다.

function TControl.GetText: TCaption;
var
  Len: Integer;
begin
  Len := GetTextLen;
  SetString(Result, PChar(nil), Len);
  if Len <> 0 then GetTextBuf(Pointer(Result), Len + 1);
end;


위 GeText함수에서 TCaption은 String형입니다.

GetText함수를 통해 String형은 넘겨 받는데
이때 C++의 AnsiString클래스에서 받습니다.

c++ AisiString클래스의  대입연산자 가 동작하고
c_str()  로 포인터에 접근할때 AisiString클래스의 c_str() 함수가 호출될것입니다.

위 두과정에서 무엇인가 꼬이는것 같습니다.

정확한 원인은 고수님들께.....


dstirng.h 파일에 C++빌더 AnsiString클래스가 정의되어있습니다.

아래와 같이 여러가지의 생성자가 있는데...

    __fastcall AnsiString(): Data(0) {}    //첫번째
    __fastcall AnsiString(const char* src);  //두번째
    __fastcall AnsiString(const AnsiString& src);//세번째..
  ....
  등등..

위의 경우  세번째 생성자가 호출되지 않을까 생각했는데...
실제로는 첫번째 생성자가 호출되더군요

그리구..
그렇다면 대입연산자 같은게 호출되어야 하는데 호출되지 않는것 같구
AnsiString& __fastcall operator =(const AnsiString& rhs);

언제 실제copy가 일어나느지 잘 모르겠더군요

그런후에 곧바로
char* __fastcall c_str() const        { return (Data)? Data: "";}
가 호출되더군요...

//-----------------------------------------------------------

하여튼  Control에 Text나 Caption은  실제 String변수가 아니라
property로 구현되어있다는것을 기억할 필요가 있구요
호출될때마다 새로 String을 만들어서 복사한후에 return한다는것도 기억하구요

가능하면 AnsiString변수에 대입한후에 string변수를 사용하는것이 좋을듯 합니다.

그리고 StrLen 보다는

AnsiString에 있는 Length라는 함수를 쓰는것이 훨씬 빠릅니다.


왜냐하면 AisiString은  Data라는 포인터 변수 한개만 가지고 있습니다만
실제 Data가 가리키는 곳에 가면
Data 앞쪽에  StrRect 이라는 12Byte가 더 생성되어있습니다.

    struct StrRec {
      int allocSiz;
      int refCnt;
      int length;
    };

StrLen으로 Length를 계산하면 0x00이 나올때까지 찾아서 length를 return하지만

String의 Length를 함수를 사용하면
저 StrRec에서 length를 바로 return해줍니다.

SetLength로 256Byte를 잡아놓고 0x00으로 모두 채워놓은경우

StrLen으로 체크하면 size가 0이지만 AisiString클래스의 Length함수를 사용하면
256이 곧바로 튀어나오게 되죠


정확한 답은 못드렸는데...
도움이 될까하여
그냥 C++빌더의 AisiString에 대해 두서없이 서술합니다.

그럼...



민간돼지 님이 쓰신 글 :
: 아래와 같이 실행하면 Data값이 제대로 나오는데요
: //////////////////////////////////////////////////////////////////
:     AnsiString TESTData;
:     TESTData = vEditInterval->Text;
:     char *Data = TESTData.c_str();
:
:     int length = StrLen(vEditInterval->Text.c_str());
:
:     for(int i= 0; i<length; i++)
:     {                                                                                                                    -
:         if(!('0'<=Data[i]&&Data[i]<='9'))
:         {
:             MessageDlg("숫자만 입력하세요", mtWarning, TMsgDlgButtons() << mbOK, 0);
:             return;
:         }
:     }
: //////////////////////////////////////////////////////////////////
: 아래와 같이 실행하면 Data값이 이상하게 나오는데 차이를 모르겠습니다.
: /////////////////////////////////////////////////////////////////
:
:     char *Data = vEditInterval->Text.c_str();
:
:     int length = StrLen(vEditInterval->Text.c_str());
:
:     for(int i= 0; i<length; i++)
:     {                                                                                                                    -
:         if(!('0'<=Data[i]&&Data[i]<='9'))
:         {
:             MessageDlg("숫자만 입력하세요", mtWarning, TMsgDlgButtons() << mbOK, 0);
:             return;
:         }
:     }
: /////////////////////////////////////////////////////////////////////////////////////////////////////
:     AnsiString TESTData;                                   //
:     TESTData = vEditInterval->Text;                    //                char *Data = vEditInterval->Text.c_str();
:     char *Data = TESTData.c_str();                    //
: ////////////////////////////////////////////////////////////////////////////////////////////////////
: 초보적인 질문이지만 비교  부탁드리겠습니다.  너무 궁금해서요

+ -

관련 글 리스트
55222 AnsiString 와 char * 비교 부탁드립니다. 민간돼지 1885 2008/11/21
55242     Re:AnsiString 와 char * 비교 부탁드립니다. 김태선 1604 2008/11/24
55250         Re:Re:AnsiString 와 char * 비교 부탁드립니다. 아제나 1550 2008/11/24
55253             Re:Re:Re:AnsiString 와 char * 비교 부탁드립니다. 장성호 1606 2008/11/24
55259                 Re:Re:Re:Re:AnsiString 와 char * 비교 부탁드립니다. 아제나 1819 2008/11/24
55247         Re:Re:AnsiString 와 char * 비교 부탁드립니다. 민간돼지 1261 2008/11/24
55233     Re:AnsiString 와 char * 비교 부탁드립니다. 아제나 1624 2008/11/21
55248         Re:Re:AnsiString 와 char * 비교 부탁드립니다. 민간돼지 1339 2008/11/24
55227     Re:AnsiString 와 char * 비교 부탁드립니다. 장성호 2194 2008/11/21
55228         Re:Re:답변 감사드립니다. 민간돼지 1367 2008/11/21
55223     저는 잘 되는데요. 근데 '-' 이건 뭐에요? 조대현.Clau 1435 2008/11/21
55226         Re:저는 잘 되는데요. 근데 '-' 이건 뭐에요? 민간돼지 1395 2008/11/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.