답변에 많은 도움이 되었습니다.
감사드리고 또 감사드려요 ^^
열심히 더 해야겠다는 생각이 드네요
장성호 님이 쓰신 글 :
: 요거는 저도 정확히 모르는 어려운 문제네요
:
: 빌더의 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(); //
: : ////////////////////////////////////////////////////////////////////////////////////////////////////
: : 초보적인 질문이지만 비교 부탁드리겠습니다. 너무 궁금해서요