AnsiString을 사용하지 않는다면, 당연히 이게 더 빠르죠.
char* a = "abc1234";
Label1->Caption = atoi(a + 3);
제리압빠. 님이 쓰신 글 :
: 오호.. SubString에서 해당 데이타 사이즈 만큼 String 동적으로 만들어서 리턴하는 거는 대강 알고 있었는데염.
: 제가 개념을 좀 다르게 가지고 있었군염.. ㅎㅎ
:
: 결국은 잘 모르고 쓰는 메소드는 독이 될수 있겠군염..
:
: char *a = "abc1234";
: char buff[4+1];
: strncpy( buff , a + 3 , 4 );
: buff[sizeof(buff)-1] = 0x00;
: int x = atoi( buff );
: Label1->Caption = buff ;
:
: 가 결과적으로 더 빠르다는 거군요...
:
: 덕분에 TControl 관련 해서 존거 배웠습니당.
: 틈틈히 빌더 공부하러 들어오는데 Q/A 같이 풀어나가는 거 많큼 좋은게 없군요.
: 이런 성실한 답변도 달아주시고 덕분에 많은 부분이 해소가 되었습니다.
: 수고~~!
:
: PS : Vcl 소스들도 좀 까봐야 되겠네요 ~~!
:
: 장성호 님이 쓰신 글 :
: : 자꾸 이런 저런 답변이 달리니까 재미있네요
: : 저는 제리압빠님의 글에 대해서만 한두가지 의견을 적어봅니다.
: :
: :
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 ));
: : :
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : : 즐 플 하세염~~~!