CString 사용

CAtlArray <CString> a;


a.add("111");

a.add("222");

  1. a[i].GetBuffer() 안됌
    a.GetAt(i) 사용
      1. GetBuffer : 수정할 경우
      2. GetString : 값을 참조 할 경우
      3. strcpy(a.GetBuffer(), a.GetString());

-The String as an array
GetLength : 설정된 문자열의 길이를 리턴
int GetLength() const;

IsEmpth : 문자열의 버퍼가 비워져 있는지 검사
BOOL IsEmpth() const;

Empty : 문자열을 삭제하여 버퍼를 비운다
void Empty();

GetAt : 특정위치의 문자값을 얻는다.

TCHAR GetAt(int nIndex) const;


operator[]

TCHAR operator[](int nIndex)const


SetAt

void SetAt(int nIndex, TCHAR ch);


operator LPCTSTR

operator LPCTSTR() const;


-Comparison

Compare :  대소문자 구분

int Compare(LPCTSTR lpsz) const;


CompareNoCase : 대소문자 구분 안함 

int CompareNoCase(PCTSTR lpsz) const;


Collate

int Collate(LPCTSTR lpsz) const;


CollateNoCase

int CollateNoCase(LPCTSTR lpsz) const;


-Extraction

Mid : 문자열의 중간부분을 추출한다.

CString Mid(int nFirst) const;

CString Mid(int nFirst, int nCount) const;


Left : 문자열의 왼쪽부분을 추출한다.

CString Let(int nCount) const;


Right: 문자열의 오른쪽부분을 추출한다.

CString Right(int nCount) const;


SpanIncludeing: 포함된 문자를 추출

CString SpanIncluding(LPCTSTR lpszCharSet) const;


SpanExcluding 



-Other Conversions

MakeUpper : 소문자를 대문자로 바꾼다.

void MakeUpper();





'and so on > 문자열' 카테고리의 다른 글

꼮꼮읽어보기  (0) 2012.12.20
msdn  (0) 2012.12.18
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10

꼮꼮읽어보기

http://bektekk.wo.to/

'and so on > 문자열' 카테고리의 다른 글

CString 사용  (0) 2013.01.31
msdn  (0) 2012.12.18
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10

msdn

http://msdn.microsoft.com/en-us/library/ms235631(v=vs.80).aspx

'and so on > 문자열' 카테고리의 다른 글

CString 사용  (0) 2013.01.31
꼮꼮읽어보기  (0) 2012.12.20
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10

UTF-8, UNICODE, ANSI - 인코딩에 대하여


 http://blog.naver.com/declspec?Redirect=Log&logNo=10092640244

'and so on > 문자열' 카테고리의 다른 글

꼮꼮읽어보기  (0) 2012.12.20
msdn  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10
[문자열] 아스키코드, 멀티바이트, 유니코드  (0) 2012.12.10

멀티/유니->utf8, utf8->멀티/유니

    const char* uni_to_utf8(const wchar_t* unicode)
    {
      static CString utf8;
      size_t len = wcslen(unicode);
      int szutf8 = WideCharToMultiByte(CP_UTF8, 0, unicode, len,  utf8.GetBufferSetLength( len * 4 ), len*4, 0, 0);
      utf8.GetBufferSetLength( szutf8 );
      return utf8.GetString();
    }
    
    const wchar_t* utf8_to_uni(const char* utf8)
    {
      static CStringW unicode;
      unicode.Empty();
      size_t len = strlen(utf8);
      int szuni = MultiByteToWideChar(CP_UTF8, 0, utf8, len, unicode.GetBufferSetLength(len), len);
      return  unicode.GetBufferSetLength(szuni);
    }
    
    const char* ansi_to_utf8(const char* ansi)
    {
      return uni_to_utf8 (CStringW(ansi));
    }
    
    const char* utf8_to_ansi(const char* utf8)
    {
      static CString ansi;
      ansi.Empty();
      ansi = utf8_to_uni(utf8);
      return ansi;
    }

'and so on > 문자열' 카테고리의 다른 글

msdn  (0) 2012.12.18
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
형변환 주의하기  (0) 2012.12.10
[문자열] 아스키코드, 멀티바이트, 유니코드  (0) 2012.12.10
wchar -> char -> String  (0) 2012.10.31

형변환 주의하기

        1. 유니코드/멀티바이트 형변환은 절대로 하지마세요

    2. 어쩔수 없이 해야 된다면 ATL 스트링으로 캐스팅을 하세요




2. 설명

멀티바이트 -> 유니코드
    

    const char* str = "...";
    const wchar_t* wstr = CStringW ( str );


    근데 CStringW  부분에

    근데 CStringW  부분에 ToWideStr 이런거 집어넣으시면 안됩니다.




    유니코드 -> 멀티바이트는

        const wchar_t* wstr = L"...";
         const char* str = CString (wstr);


    CString 대신 WCharToChar 요런거 쓰시면 안되구요
  

  안되는 이유는
    WCharToChar 같은 함수에서 내부적으로
    malloc 을 호출을 하는데
    쓸때없이 메모리를 낭비하는 거라서 안됌





[문자열] 아스키코드, 멀티바이트, 유니코드

※character ser이란?

예전에 미국에서 영어를 표한하기 위해 아스키 코드라는 character set을 만들었다.


character set이란 숫자와 문자의 관계? 또는 문자표 라고 생각하면 된다.


예를 들어 아스키 코드같은 경우에는 char형으로 저장을 하는데

 
char가 문자형이라고 해봐야 일단은 1바이트의 메모리공간으로 메모리에 존재하는 것은 그저 2진수 숫자 뿐이다.


이러한 char로 문자를 표현할 수 있는 이유는 숫자와 문자사이의 표를 만들어 표준으로 정하고 사용하기 때문이다.


예를 들면 숫자 65는 A이다. 숫자 97은 a이다. 이런 형식이다.


참고로, 대문자랑 소문자랑 다른 수 이다. 따라서 A == a 는 거짓이다.




※아스키 코드

char은 8비트로 2의8승-1 로 총 255가지의 숫자를 가지고 있다.


그러므로 아스키 코드는 255가지의 문자를 표현할 수 있을거라 생각할수도 있지만 1비트는 따로 사용하는 용도가 정해져 있다.


그러므로 총 7비트만큼 문자를 표현하는데 사용하고 있다.


아스키 코드표는 외울 필요가 없고, 인터넷에 아스키코드를 검색하면 표를 쉽게 찾을 수 있으니 궁금할때마다 참고 하면된다.




※멀티 바이트 코드

아스키 코드는 1바이트로 문자를 표현한다.(1비트는 어떠한 이유로 사용하지않음)


1바이트는 7비트로 128가지의 문자를 표현하는데 세상의 문자가 128가지는 아니다.


한글도 있고 일본어도 있다. 이러하다보니 1바이트로 처리하기에는 표현할 수 있는 범위가 너무 좁았다.


그 문제점을 해결하기위한 방법중 하나가 멀티 바이트 코드다.


멀티바이트 코드는 영어같은 아스키 코드에 포함되는 문자는 1바이트로 표현하고, 포함되지 않는 문자는 2바이트로 포현한다.


따라서 'abc안녕'와 같은 문자열은 'abc'는 3바이트, '안녕'은 4바이트에 NULL문자 1바이트로 총 8바이트가 할당된다.


얼핏보면 굉장히 효율적인 구조라 할수도 있다.


물론 멀티바이트가 나쁜건 아니지만 몇가지 문제점을 가지고 있다.


영어는 1바이트로 표현하고 한글은 2바이트로 표현하기 때문에 문자열을 다루는 프로그래밍을 할때 코딩이 어렵다.


또한 strlen같은 함수를 사용했을시 한글을 2자리로 인식해서 버그의 소지가있다.


물론 이것을 숙지하고 프로그래밍을 한다면 메모리를 효과적으로 사용할 수는 있겠으나 그것은 프로그래머를 피곤하게 하고 1바이트 문자인지 2바이트 문자인지 체크하는 코드 때문에 성능의 저하가 생길것이다.

따라서 최근 사용되는 character set은 유니코드이다.




※유니코드

유니코드는 멀티바이트와 달리 한글이든 영어든 항상 2바이트의 메모리를 할당한다.


아스키코드의 한계점과 멀티바이트의 문제점을 해결할 수 있는 형태이다.


하지만 이러한 유니코드의 경우에도 문제점이있다.


바로 strlen으로 길이를 조사했을때 'avb하나'를 총 10글자로 인식해버린다. strlen은 아스키 코드 문자열을 위한 함수이기 때문이다.


흔히들 사용해온 printf, scanf등은 전부 아스키코드를 위한 함수였던 것이다.


유니코드 문자열을 위한 입출력 함수는 따로 존재한다. 예를 들면 printf의 유니코드 버전은 wprintf이다.


strlen의 유니코드 버전은 wcslen이고 strcat, strcpy, strcmp, strncpy의 유니코드 버전은 wcscat, wcscpy, wcscmp, wcsncpy이다.


유니코드는 char 형이 아닌 wchar_t형을 사용한다. wchar_t는 unsigned short를 typedef으로 재정의 한 것인데 2바이트다.


또한 유니코드는 일반적인 문자열을 대입해선 안된다.


예를들어 "abc"의 경우 아스키 코드 문자열이다. 유니코드 문자열은 앞에L을 붙여주어야 한다. 예를들어 L"abc"가 유니코드 문자열이다.


windows.h에 재정의 되어있는 WCHAR은 wchar_t이다.


출처

http://hardcoding.egloos.com/557949


wchar -> char -> String


  • wchar -> char로 문자열을 변환 하려고 하는데,
    인터넷에서 찾은 함수는 메모리 할당하고 해제 해주지 않고 
    그 메모리를 포인터로 넘겨줘서 메모리 사용에 좋지 못할 것 같아서 수정하였다.

  • 함수 WCharToChar,  ToUTF8Str 두개 사용 

  • 메모리를 할당 받아서 WCharToChar 함수로 포인터 넘겨줌 



  // wchar -> char

void WCharToChar(const wchar_t* pwstrSrc, char * pstr)

{

setlocale(LC_ALL, "korean"); 

assert(pwstrSrc);


#if !defined _DEBUG

int len = 0;

len = (wcslen(pwstrSrc) + 1)*2;

char* pstr      = (char*) malloc ( sizeof( char) * len);


WideCharToMultiByte( 949, 0, pwstrSrc, -1, pstr, len, NULL, NULL);

#else

int nLen = wcslen(pwstrSrc);

int count = 0;


count = wcstombs(pstr, pwstrSrc, nLen+1); // 여기서 와이드에서 멀티 바이트로 변환

#endif

}



  std::string ToUTF8Str(const WCHAR *S, const int NumChars)

{

std::string Result = "";

int BufferLen = NumChars + 1;


char* pstr      = (char*) malloc ( sizeof( char) * BufferLen + 1);


WCharToChar(S, pstr); // 여기서 호출 해서 


Result.assign(pstr); // String 으로 변환 해준 후 

free(pstr);            // 메모리 해제 


return Result;

}



만약 wcstombs() 사용하는데 뒤에 부분이 잘린다면 

pstr의 크기를 2배로 늘려주면 됨 

버퍼 크기 문제였음ㅜㅜ


문자열 짜잉나 !!

문자열 처리함수 정리(멀티바이트 -> 유니코드)

멀티 바이트 환경에서 사용하던 함수를 유니코드 환경에서 사용하려고 하면 사용이 안된다.

처음에 VS2008을 사용하면서 예전 책을 보면서 공부할 때 가장 많이 머리가 아프던 문제였다.

유니코드 환경에서 사용 할 수 있게 정의가 되어진 함수들은 같은 함수명을 써도 자동으로 처리가 되기 때문에

특별히 신경을 쓸 일은 없었다. 그러나 문자열처리 함수 같은경우는 아예 함수 이름이 바뀌었기 때문에 모른다면 사용 할 수가 없다.

그래서 문자열 처리 함수를 정리 할 겸 유니코드 환경에서 사용 할 수 있는 문자열 처리 함수를 정리해 보았다.

일단 기본적으로 멀티 바이트 환경에서 문자열 처리 함수의 접두어는 str 이었다 strlen, strcat, strstr 등등

그러나 유니코드 환경에서 접두어는 wcs이다. 이것만 기억해 둔다면 이미 문자열처리 함수의 절반은 안것이다.


1-1.strcpy -> wcscpy

:문자열을 복사하는 함수이다

원형 :

wchar_t *wcscpy(
wchar_t *strDestination, 복사 당하는 대상
const wchar_t *strSource 복사 하려는 소스
);

ex)

TCHAR str[256];

wcscpy(str,L"안녕하세요");

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요" 문자열 출력



1-2. strncpy -> wcsncpy

:입력한 사이즈 만큼 문자열을 복사하는 함수이다

원형 :

wchar_t *wcsncpy(
wchar_t *strDest, 복사 당하는 대상
const wchar_t *strSource, 박사 하려는 소스
size_t count 복사하려는 개수
);

ex)

TCHAR str[256];

memset(str,0,sizeof(str)); NULL값으로 배열을 초기화

wcsncpy(str,L"안녕하세요", 2);

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕" 문자열 출력


2. strlen -> wcslen

: 입력 받은 문자열의 길이를 반환해준다.

sizeof와 다른점은 sizeof는 배열의 전체크기를 반환해주고

wcslen은 중간에 NULL을 만나면 NULL까지의 길이만 반환한다.

원형 :

size_t wcslen(
const wchar_t *str
);


3-1.strcat -> wcscat

: 두 문자열을 이어준다

원형 :

wchar_t *wcscat(
wchar_t *strDestination,
const wchar_t *strSource
);

ex)

wcscpy(str,L"안녕하세요");
wcscat(str,L"오냐");

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요오냐" 출력


3-2.strncat -> wcsncat

: 입력한 사이즈만큼 대상에 소스를 이어준다

원형 :

wchar_t *wcsncat(
wchar_t *strDest,
const wchar_t *strSource,
size_t count
);

ex)

wcscpy(str,L"안녕하세요");
wcsncat(str,L"오냐",1);

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요오" 출력


4-1.strcmp -> wcscmp

:대소문자를 구분하지 않고 문자열을 비교한다.

원형 :

int wcscmp(
const wchar_t *string1,
const wchar_t *string2
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"안녕하세요");

wcscpy(str2,L"하이");

if(wcscmp(str,str2) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "다르다" 출력


4-2.strncmp -> wcsncmp

:지정한 사이즈만큼 대소문자를 구분하지 않고 문자열을 비교한다.

원형 :

int wcsncmp(
const wchar_t *string1,
const wchar_t *string2,
size_t count
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"안녕하세요");

wcscpy(str2,L"안하이");

if(wcsncmp(str,str2,1) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



5-1. stricmp -> wcsicmp

:대소문자를 구별하지 않고 문자열을 비교

원형 :

int _wcsicmp(
const wchar_t *string1,
const wchar_t *string2
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"ABCDE");

wcscpy(str2,L"abcde");

if(wcsicmp(str,str2) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



5-2. strnicmp -> wcsnicmp

:대소문자를 구별하지 않고 문자열을 비교

원형 :

int _wcsnicmp(
const wchar_t *string1,
const wchar_t *string2,
size_t count
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"ABCDE");

wcscpy(str2,L"abcdefgh");

if(wcsnicmp(str,str2,5) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



6-1.strchr -> wcschr

:문자열에서 한 문자를 찾아 그 문자가 있는 주소를 반환하여 준다. (문자열의 처음부터 검사한다)

:만약에 찾지 못했을 경우에는 NULL값을 반환해준다

원형:

wchar_t *wcschr(
wchar_t *str,
wchar_t c
);

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR dd = L'요';
TCHAR * ddd;

ddd = wcschr(str2,dd);

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = 0,0에 "요안녕하세요하이" 출력



6-2.strrchr -> wcsrchr

:문자열에서 한 문자를 찾아 그 문자가 있는 주소를 반환하여 준다. (문자열의 맨 마지막부터 검색한다)

:만약에 찾지 못했을 경우에는 NULL값을 반환해준다

원형:

wchar_t *wcsrchr(
wchar_t *str,
wchar_t c
); // C++ only

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR dd = L'요';
TCHAR * ddd;

ddd = wcsrchr(str2,dd);

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = 0,0에 "요하이" 출력



7.strstr -> wcsstr

:문자열에서 원하는 문자열을 찾아준다.

원형 :

wchar_t *wcsstr(
wchar_t *str,
const wchar_t *strSearch
);

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR * ddd;
ddd = wcsstr(str2,L"안녕");

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = "안녕하세요하이" 출력


8.strpbrk -> wcspbrk

: 첫번째 인수로 받은 문자열에서 두번째 인수로 받은 문자열중 한문자라도 빨리 나오는 문자의 주소를 반환해준다.

원형 :

wchar_t *wcspbrk(
wchar_t *str,
const wchar_t *strCharSet
); // C++ only

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR * ddd;

ddd = wcspbrk(str2,L"녕세"); '녕' 이나 '세' 이 두글자 중에 빨리 나오는 문자의 주소를 출력해준다

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = "녕하세요하이" 출력



9.strtok -> wcstok

: 첫번째 매개변수로 받은 문자열을 두번째 매개변수로 받은 토큰 문자로 나누어준다.

원형 :

wchar_t *wcstok(
wchar_t *strToken,
const wchar_t *strDelimit
);

ex)

wcscpy(str2,L"나의'가치'는 내가 결정하고, 당신의 '가치'는 당신이 결정한다");
TCHAR * ddd;

ddd = wcstok(str2,L" ,'"); //토큰은 여러개를 지정할 수 있다. 여기서는 공백(' ')과 콤마(',') 작은따옴표(')로 지정했다.
while(ddd != NULL){
TextOut(hdc,0,i,ddd,wcslen(ddd));
ddd = wcstok(NULL,L" ,'"); //검색을 계속 해야하기 때문에 NULL값을 매개변수로 넣어준다

i+=20;
}



wcstok의 방식은 문자열에서 처음 토큰을 발견하면 그 주소를 저장하고 두번째 토큰을 찾아내면 그 토큰을 NULL로 만들고

처음 토큰 주소를 반환해준다. 또한 wcstok함수는 함수 중간 결과를 자체적으로 정적변수를 사용하고 있다. 그렇기 때문에

계속 검색을 하고 싶으면 첫번째 매개변수로 NULL을 넣어주면 문자열이 끝날때 까지 검색을 한다.

검색이 끝나면 NULL을 반환해 준다.

wcstok함수도 매개변수로 받은 데이터를 손상시키기 때문에 데이터가 손상되지 않게 하려면 다른곳에 복사한 후에 써야한다.

또한 함수 자체적으로 정적 변수를 사용하고있기 때문에 멀티 스레드 환경에서 동시에 호출될 염려가 있으므로

동시에 호출되지 않도록 보호해 주어야 한다.

:출력 =

나의

가치

내가

결정하고

당신의

가치

당신이

결정한다



10-1.strset -> wcsset

: 첫번째 매개변수로 받은 문자열을 NULL문자 전까지 모두 두번째 문자로 바꾼다

원형 :

wchar_t *_wcsset(
wchar_t *str,
wchar_t c
);

ex)

wcscpy(str,L"ABCDE");

wcsset(str,L'd');
TextOut(hdc,0,0,str,wcslen(str));

:출력 = 0,0에 "ddddd" 문자열이 출력된다



10-2.strnset -> wcsnset

: 첫번째 매개변수로 받은 문자열을 입력받은 사이즈 만큼 두번째 문자로 바꾼다

원형 :

wchar_t *_wcsnset(
wchar_t *str,
wchar_t c,
size_t count
);

ex)

wcscpy(str,L"ABCDE");

wcsnset(str,L'd',2);
TextOut(hdc,0,0,str,wcslen(str));

:출력 = 0,0에 "ddCBD" 문자열이 출력된다



11.

strupr -> wcspur

strlwr -> wcslwr

: 지정한 문자열을 대문자로 치환(wcspur) 하거나 소문자로 치환(wcslwr)한다.

: 단 대문자나 소문자만 치환이 되고 한글이나 숫자는 치환되지 않는다.

: 이 함수도 매개변수로 받은 문자열을 변형시키기 때문에 변형되어서는 안되는 문자열이면 복사를 해놓고 사용해야 한다.

wcscpy(str,L"1abcdeABCDE아");

wcsupr(str);
TextOut(hdc,0,0,str,wcslen(str));

wcslwr(str);
TextOut(hdc,0,20,str,wcslen(str));

:출력 =

0,0에 "1ABCDEABCDE아" 출력

0,20에 "1abcdeabcde아" 출력

12.strrev -> wcsrev

: 지정한 문자열을 역순으로 배치한다. 한글도 역순으로 배치된다.

: 이 함수도 매개변수로 받은 문자열을 변형시키기 때문에 변형되어서는 안되는 문자열이면 복사를 해놓고 사용해야 한다.

원형 :

wchar_t *_wcsrev(
wchar_t *str
);

ex)

wcscpy(str,L"1abcdeABCDE아");

wcscpy(str2,L"나의 '가치'는 내가 결정하고, 당신의 '가치'는 당신이 결정한다");

wcsrev(str);
wcsrev(str2);

TextOut(hdc,0,0,str2,wcslen(str2));
TextOut(hdc,0,20,str,wcslen(str));

:출력 =

0,0에 "다한정결 이신당 는'치가' 의신당 ,고하정결 가내 는'치가' 의나" 출력

0,20에 "아EDCBAedcba1" 출력