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== L 옹 P의 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.