LPCSTR, LPCTSTR 및 LPTSTR


109

LPCSTR, LPCTSTR및 의 차이점은 무엇입니까 LPTSTR?

왜 우리가로 문자열을 변환하는이 작업을 수행해야합니까 LV/ _ITEM구조 변수 pszText:

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

2
"문자열"이 정확히 어떤 유형인지 말할 수 있습니까? (예 : CString)
John Sibly

답변:


122

질문의 첫 부분에 답하려면 :

LPCSTRconst 문자열에 대한 포인터 (LP는 Long Pointer를 의미 함 )

LPCTSTRconst TCHAR문자열에 대한 포인터입니다 ( TCHAR프로젝트에 UNICODE가 정의되었는지 여부에 따라 와이드 문자 또는 문자).

LPTSTR상수가 아닌 TCHAR문자열에 대한 포인터입니다.

과거에 이것에 대해 이야기 할 때, 우리는 단순성을 위해 "pointer to a"문구를 생략했지만, lightness-races-in-orbit에서 언급했듯이 그것들은 모두 포인터입니다.

이것은 C ++ 문자열을 설명 하는 훌륭한 코드 프로젝트 문서입니다 (다른 유형을 비교하는 차트는 2/3 참조).


18
모든 잘못된. 이러한 것들은 문자열이 아닙니다. 그것들은 모두 포인터입니다. -1
궤도의 밝기 경주

8
@LightnessRacesinOrbit 당신은 기술적으로 정확합니다-비록 제 경험상 C ++에서 문자열 유형을 언급 할 때 간결함을 위해 "a ....에 대한 포인터"설명을 생략하는 것이 일반적인 관행입니다
John Sibly

2
@JohnSibly : C에서는 그렇습니다. C ++에서는 절대 안됩니다 !!
궤도의 가벼운 경주

4
codeproject 기사는 15 년 전에 작성되었으며 업데이트되지 않는 한 유니 코드 문자가 항상 2 바이트라는 잘못된 가정을 포함하고 있습니다. 그것은 완전히 잘못되었습니다. UTF16조차도 가변 길이입니다 ... 와이드 문자는 UCS-2로 인코딩되고이 컨텍스트에서 "유니 코드"는 UCS-2를 참조한다고 말하는 것이 훨씬 좋습니다.
u8it

1
흠 ...이 경우 @LightnessRacesinOrbit, C ++에서 C- 문자열을 참조 할 때 "포인터 ..."를 생략해도된다는 부록을 추가합니다. (부패 된) 문자열 리터럴 또는 C로 작성된 코드와 인터페이스 / 작업 할 때 C ++ 유형 대신 C 유형에 의존하거나 extern "C". 그 외에도 "포인터"비트 또는 C 문자열과 같은 특정 설명이 필요합니다.
저스틴 시간 - 분석 재개 모니카

87

빠르고 더러운 :

LP== LP의 ointer. 포인터 또는 문자 *

C= C onst,이 경우에는 문자열이 const가 아니라 포인터가 const라는 것을 의미한다고 생각합니다.

STR이다 문자열

T컴파일 옵션에 따라 다양한 문자 또는 문자 (TCHAR)입니다.


16
T는 와이드 문자가 아니라 다양한 문자 유형을위한 것입니다. W는 와이드입니다 (WCHAR에서와 같이). UNICODE가 정의 된 경우 TCHAR == WCHAR, 그렇지 않으면 TCHAR == CHAR입니다. 따라서 UNICODE가 정의되어 있지 않으면 LPCTSTR == LPCSTR입니다.
jalf

10
이것이 내가 "컴파일 옵션에 따라"를 쓴 이유입니다
Tim

14
나는 이러한 유형의 설명을 정말 좋아합니다. :). 대단히 감사합니다
Dzung Nguyen

@jalf, 그래서 T는 무엇을 의미합니까?
Pacerier


36

8 비트 AnsiStrings

  • char: 8 비트 문자-기본 C / C ++ 데이터 유형
  • CHAR: 별칭 char-Windows 데이터 유형
  • LPSTR: ( L ong P ointer) 의 null로 끝나는 문자열CHAR
  • LPCSTR: ( L ong P ointer) 의 상수 null로 끝나는 문자열CHAR

16 비트 유니 코드 문자열

  • wchar_t: 16 비트 문자-기본 C / C ++ 데이터 유형
  • WCHAR: 별칭 wchar_t-Windows 데이터 유형
  • LPWSTR: ( L ong P ointer) 의 null로 끝나는 문자열WCHAR
  • LPCWSTR: ( L ong P ointer) 의 상수 null로 끝나는 문자열WCHAR

UNICODE정의 에 따라

  • TCHAR: WCHARUNICODE가 정의 된 경우 별칭 ; 그렇지 않으면CHAR
  • LPTSTR: ( L ong P ointer) 의 null로 끝나는 문자열TCHAR
  • LPCTSTR: ( L ong P ointer) 의 상수 null로 끝나는 문자열TCHAR

그래서

| Item              | 8-bit        | 16-bit      | Varies          |
|-------------------|--------------|-------------|-----------------|
| character         | CHAR         | WCHAR       | TCHAR           |
| string            | LPSTR        | LPWSTR      | LPTSTR          |
| string (const)    | LPCSTR       | LPCWSTR     | LPCTSTR         |

보너스 읽기

TCHAR텍스트 문자 ( archive.is )


4
이 답변은 너무 새롭기 때문에 절대로 정상에 오르지 않을 것입니다. 정말 고칠 필요가 있습니다. 이것은 지금까지 가장 좋은 대답입니다.
Dan Bechard

이것은 작업에서 유니 코드 프로젝트를 수행하는 동안 정말 많은 도움이됩니다. 감사!
Yoon5oo 2018-06-27

좋은 대답입니다. 유니 코드 버전은 UTF16을 사용하므로 각 16 비트 청크는 문자가 아니라 코드 단위라는 점을 추가 할 가치가 있다고 생각합니다. 이름은 역사적입니다 (유니 코드 === UCS2 인 경우).
Margaret Bloom

5

John과 Tim의 대답에 추가합니다.

Win98 용으로 코딩하지 않는 한, 애플리케이션에서 사용해야하는 6 개 이상의 문자열 유형 중 두 가지만 있습니다.

  • LPWSTR
  • LPCWSTR

나머지는 ANSI 플랫폼 또는 이중 컴파일을 지원하기위한 것입니다. 오늘날에는 예전만큼 관련성이 없습니다.


2
@BlueRaja, 나는 주로 내 대답에서 C 기반 문자열을 언급했습니다. 그러나 C ++의 std::string경우 여전히 ASCII 기반 문자열이기 때문에 피하고 std::wstring대신 선호 합니다.
JaredPar

1
ASCII (* A) 또는 widechar (* W) 버전의 함수를 직접 호출하지 않는 한 LPTSTR 및 LPCTSTR을 사용해야합니다. 컴파일 할 때 지정한 문자 너비의 별칭입니다.
osvein

... 그리고 마이크로 소프트가 *AUTF-8 코드 페이지와 호환되는 WinAPI 버전 을 만들기 위해 노력하고 있기 때문에 갑자기 훨씬 더 관련성이 높아졌습니다. ; P
저스틴 시간 - 분석 재개 모니카

4

질문의 두 번째 부분에 답하려면 다음과 같은 작업을 수행해야합니다.

LV_DISPINFO dispinfo;  
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);

MS의 LVITEM구조체에는 LPTSTR, 즉 변경 가능한 T- 문자열 포인터 가 있기 때문에LPCTSTR . 당신이하는 일은

1) string( CString추측에 따라)를 LPCTSTR(실제로는 읽기 전용 포인터로 문자 버퍼의 주소를 얻는 것을 의미합니다)

2) 읽기 전용 포인터를 const-ness 를 캐스트하여 쓰기 가능한 포인터로 변환 하십시오.

그것은 dispinfo당신의 ListView전화가 그것을 통해 쓰기 를 시도하게 될 가능성이 있는지 여부에 사용되는 것에 달려 pszText있습니다. 만약 그렇다면, 이것은 잠재적으로 매우 나쁜 일입니다. 결국 당신은 읽기 전용 포인터를 받고 그것을 쓰기 가능으로 취급하기로 결정했습니다. 아마도 그것이 읽기 전용 인 이유가있을 것입니다!

그것은 경우 CString당신이 당신과 함께 작업하고 사용할 수있는 옵션이 string.GetBuffer()의도적으로 당신에게 쓰기를 준다을 - LPTSTR. 그런 다음 ReleaseBuffer()문자열이 변경되면 호출하는 것을 기억해야합니다 . 또는 로컬 임시 버퍼를 할당하고 거기에 문자열을 복사 할 수 있습니다.

99 %의 시간이 불필요하며 유언장으로 취급 LPCTSTR하는 LPTSTR것이 효과가 있지만 언젠가는 예상치 못한 일이 발생합니다 ...


1
C 스타일 캐스트를 피하고 xxx_cast<>()대신 사용해야 합니다.
하퍼

@harper 당신 말이 맞아요.하지만 나는 OP를 인용하고 있었는데, 그게 그가 요청한 코드입니다. 내가 직접 코드를 작성했다면 확실히 사용했을 것입니다.xxx_cast<> 두 개의 다른 대괄호 기반 캐스팅 스타일을 혼합 것보다 !
AAT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.