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
[60292] Re:Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리...
Nibble [gameover] 1228 읽음    2010-02-23 06:12
ㅋㅋ 정말 황당한 코드 보고 뿜었습니다.
그렇지만, 그런 코드를 짜서 원하지 않는 결과를 얻었던 분은 메카니즘을 이해하게 될 가능성이 크네요 : )

원 질문자분의 질문이 가지는 정보량보다
제키압빠님과 장성호님의 굴비에서 만들어진 정보량이 더 큰 듯 싶군요.
모두 즐프.

장성호 님이 쓰신 글 :
: 자꾸 이런 저런 답변이  달리니까 재미있네요
: 저는 제리압빠님의 글에 대해서만 한두가지 의견을 적어봅니다.
:
: str.t_str(); 이부분은?
:
: 앞의 저의 답변에도 얘기했듯이 2009에서
: 기본 String이 AnsiString이 아니라 UnicodeString이라서 그럴것입니다.
:
: AnsiString으로 하면 여전이 str.c_str()로 char *를 얻어올것입니다.
:
: ---------------------------------------------------------------------------------
: 그리고 제리압빠님의 코드에서
: Edit->Text 를 가져오는 부분에 대해
:
: 제리압빠님의 코드중에 짭게 부분에 대해 조금 의견을 달겠습니다.
:
: // 잛게 
:     Label1->Caption = Edit1->Text.SubString( 4 , Edit1->Text.Length() - 3  ); 
:     x = Label1->Caption.ToInt(); 
:     ShowMessage( x ); 
: 

:
: 제리압빠님뿐만 아니라 많은 분들이 위와같은 식으로 코딩하는 경우를 왕왕 보아서요
:
: 위 코드에서
: Label1->Caption 과  Edit1->Text 에 대한 접근은
: TControl 클래스의 Caption 프로퍼티와 Text 프로퍼티에 접근합니다.
: TControl에서 Caption과 Text는 근본적으로 똑같습니다.
:
: 문제는
:   TControl의 Caption을 읽을때
:   그냥 내부 String변수를 return하지 않는다는 것입니다.
:  
:   여러단계의 과정을 거쳐서 String결과를 return합니다.
:
: TControl클래스 Caption가져올때 소스
: 다음은 TControl클래스이 Caption이나  Text를 가져올때 호출되는 GetText함수 소스입니다.
:
:
: 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;
: 
: function TControl.GetTextLen: Integer;
: begin
:   Result := Perform(WM_GETTEXTLENGTH, 0, 0);
: end;
: 
: function TControl.GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;
: begin
:   Result := Perform(WM_GETTEXT, BufSize, Longint(Buffer));
: end;
: 

:
: C++Builder로 변환하면 다음과 같습니다.
:
:
: String __fastcall TControl::GetText()
: {
:   int Len=GetTextLen();      // 문자열의 길이를 확인합니다.
:   String Result;                  // String변수를 새로 선언하고 
:   Result.SetLength(Len);   // 문자열 길이만큼 메모리를 확보합니다. 
:   if(Len!=0)
:     GetTextBuf(Result.c_str(), Len + 1); //확보된 buffer에 WM_GETTEXT로 string을 받아옵니다.
: 	
:   return Result;
: }
: 
: int __fastcall TControl::GetTextLen()
: {
:    return this->Perform(WM_GETTEXTLENGTH, 0, 0);
: }
: 
: int __fastcall TControl::GetTextBuf(char *Buffer,int BufSize)
: {
:   return this->Perform(WM_GETTEXT, BufSize, Longint(Buffer));
: }
: 

:
: TEdit든 TLabel이든 VCL의 모든 Control의 Caption이나 Text에 접근할때 마다 위 함수들이 호출됩니다.
:
: 제라아빠님의 코드에서는?
:
: // 잛게 
:     Label1->Caption = Edit1->Text.SubString( 4 , Edit1->Text.Length() - 3  ); 
:     x = Label1->Caption.ToInt(); 
:     ShowMessage( x ); 
: 

:
: 위 코드에서는
: TControl::GetText가 3번 호출되었구
: TControl::SetText가 1번 호출되었습니다.
: (SetText내부적으로 GetText가 한번 호출되니 GetText는 4번이 되겠네요)
:
: 또한 메세지 핸들러 함수에서
:   WM_GETTEXT,WM_SETTEXT , WM_GETTEXTLENGTH등을 받아서 처리하는 부분도 있구요
:
: 그러니까 TEdit의 Text값을 한번 가져오는데 굉장히 복잡한 과정에
: 여러함수들이 호출되어진다는 것입니다.
:
: -----------------------------------------------------------------------
: 그리고 또 하나
:
:   ShowMessage( x );  //이  부분에서는
:  
:   ShowMessage는 기본적으로 int형을 받지 않고 String형을 받습니다.
:  즉 ShowMessage( x) 할때 String클래스에서
:   숫자를 IntToStr함수 등을 통해 문자열로 다시 변환하게 됩니다.
:
: 뭐 제리아빠님은 그냥 제대로 Label1->Caption에 내용이 들어있나 확인하기 위함인것 같지만..
:
:
: 결론적으로..
:  String변수하나 선언해두고
: 거기에다가 Edit->Text를 받아서 처리하는것이
: 속도면에서 훨씬더 빠를것입니다.
:
: 일부러 트집잡으려구 답변단것은 아니구요
: 앞서 얘기했듯이 많은 BCB , Delphi 개발자들이 TEdit등 TControl의 Text값을 가져오는것이
: 그냥 내부 String변수를 return해주는것으로 착각하고 코딩하는 경우를 왕왕 보아서 댓글 단것입니다.
:
: 진짜 황당한 코드
: 심지어  다음과 같은식의 코드도 보았습니다.
:
: strcpy( Edit1->Text.c_str() , "문자열 복사") ;
: 


: 위에 GetText 의 vcl소스를 보면 알수 있듯이
: TEdit의 Text나 TLabel의 Caption은 내부 변수를 return한느것이 아니라
: 새로 메모리를 할당해서 내용을 복사해 return하는 것이므로
: 에러가 나지 않더라도(에러날수도 있음)
: 실제 Edit->Text에는 아무 변화를 줄수 없는 코드가 되죠
:
: TControl의 Text나 Caption프로퍼티에 대한 비슷한 착각에서 코딩문제일것 같구요..
:
: 그럼..
:
:
:
: 제리압빠. 님이 쓰신 글 :
: : 소스코드 일부만 있는거 같은데용..
: : str.t_str().... 이 부분은 2009에서 새로 지원하는 String의 메소든가 보군요..
: :
: : 저는 아직 6.0 을 쓰는 처지라..유유
: : 음.. 작성하신 코드 상으로는 풀어보면.
: : 1) char 어레이를 초기화 한다.
: : 2) String 형 데이타에서 특정 부위(?) 만큼의 숫자 필드 영역을 잘라서 char배열에 담는다.
: : 3) int형으로 형변환 한다.
: : 4) int형을 다시 형변환 하여 String( Caption )에 담는다..
: :
: : 순으로 진행이 되는데요..
: :
: : 나열한거에 보다 시피 형변환이 좀 빈번히 발생하는게 아닌가 싶네요.
: : 윗분들 말씀하신 거에 좀더 사족을 달아 보자면..
: :
: : 위에서 거치는 형변환을 좀 줄이자 입니다.
: : 윗분들 코드 사례를 보면 char *어레이 형 데이타가 필요 없어지지요.
: : ( 내부에서 쓸일이 없다면 말입니다.. )
: : 이부분을 좀 줄여서 2단게로 만들어 버리는게 제 개인적인 생각으로 좀 더 나은 생각이 아닌가 사려 됩니다.
: :
: :     // 1 필요한 데이타 부분을 Label에 바로 담아 버립니다.
: :     Label1->Caption = Edit1->Text.SubString( 4 , Edit1->Text.Length() - 3  );
: :     // 2. Label1을 버퍼로 사용하였으므로 가공을 위한 인트형으로 바로 세트 한다.
: :     int ibuff = Data.ToInt();
: :
: : 이렇게 되면 좀 더 효율이 올라가지 않으려나요...
: : Label을 사용하지 않을 계획이라면 윗분들의 예제 처럼 바로 Int 변수에 결과를 담아 버리는 것도 괜챦구요..
: :
: : 만약 위에 사용하신 데이타가 "abc1234" 가 Fixed length 타입의 전문 이라고 하면...아래 처리 부분 처럼 하면
: : 될 듯 싶네요.. fixed length 인 경우 가공작업이 좀 필요하기도 합니다. 널스트링 이 없는 관계로.. 하지만 파일에서
: : 로드하는 경우라면 파일에 구조체 통으로 바이너리 타입 저장 이라면 별 문제 업겠지용.
: : //---------------------------------------------------------------------------
: :
: : #pragma pack( push , 1);
: : typedef struct tag_x
: : {
: :     char ABC[3];
: :     char NUMS[4];
: : }st_x;
: :
: : #pragma pack(pop);
: :
: : void __fastcall TForm1::Button1Click(TObject *Sender)
: : {
: :     // 원본 ..
: :     String Data = Edit2->Text;
: :     char buff[4+1];
: :     int  x;
: :     memset( buff , 0x00 , sizeof( buff ));
: :     strncpy( buff , (Edit2->Text.c_str())+3 , Edit2->Text.Length() - 3 );
: :
: :     x = atoi( buff );
: :     ShowMessage( x );
: :
: :
: :     // 잛게
: :     Label1->Caption = Edit1->Text.SubString( 4 , Edit1->Text.Length() - 3  );
: :     x = Label1->Caption.ToInt();
: :     ShowMessage( x );
: :
: :     // 고정전문 방식.  뒷부분에 다른 문자열이 있다면 잘라 담는 처리를 위한 버퍼 필요함( 1234 ) 다음
: :     st_x sbuff;
: :     memcpy( &sbuff , Edit2->Text.c_str() , sizeof( sbuff ));
: :     Label3->Caption = sbuff.NUMS;
: :     ShowMessage( atoi( sbuff.NUMS ));
: :
: : }
: : //---------------------------------------------------------------------------
: :
: : 즐 플 하세염~~~!

+ -

관련 글 리스트
60276 황당한 일이 생겨서리... 복이 1630 2010/02/21
60277     Re:황당한 일이 생겨서리... 한수동 1393 2010/02/21
60278         Re:Re:황당한 일이 생겨서리... 장성호 1604 2010/02/22
60282             Re:Re:Re:황당한 일이 생겨서리... Nibble 1468 2010/02/22
60283                 Re:Re:Re:Re:황당한 일이 생겨서리... Lynx 1378 2010/02/22
60284                     Re:Re:Re:Re:Re:황당한 일이 생겨서리... Nibble 1326 2010/02/22
60288                         Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... 제리압빠. 1390 2010/02/22
60291                             Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... 장성호 1521 2010/02/22
60296                                 Re:Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... 제리압빠. 1194 2010/02/23
60298                                     Re:Re:Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... Nibble 1228 2010/02/23
60299                                         Re:Re:Re:Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... 제리압빠. 1424 2010/02/23
60292                                 Re:Re:Re:Re:Re:Re:Re:Re:황당한 일이 생겨서리... Nibble 1228 2010/02/23
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.