Mi tchar, wchar, lpstr, lpwstr, lpctstr (stb)

Sok C ++ programozók, akik a Windows gyakran összekeverik felett, hogy ezek a furcsa azonosítók TCHAR, LPCTSTR. Ebben a cikkben megpróbálom a legjobb módja annak, hogy pont az I. és a köd kétség.
Te csoda.
Megkérdezhetem egy macska.
Általában, a karakter a string lehet reprezentálni a 1-edik bájt és 2 bájt.
Jellemzően egy byte-os karakter kódolás ANSI szimbólum képviselteti magát a kódolást minden angol karaktereket. A 2-bájtos karaktereket Unicode, ami lehet az összes többi nyelv a világon.
Visual C ++ fordító támogatja char és wchar_t mint egy beépített adattípusok és ANSI kódolások UNICODE.Hotya konkrétabb meghatározását Unicode, de érthető, hogy ez a Windows a 2 byte-os kódolás több nyelv támogatása alkalmazásokat.
Hogy képviselje a 2 byte Unicode kódolás egy Microsoft Windows-UTF16 kódolást.
Microsoft lett az egyik első vállalat, amely megkezdte az Unicode támogatást az operációs rendszer (család Windows NT).
Mi a teendő, ha azt szeretné, hogy a C / C ++ kódot is független a kódolás és az eltérő kódolási mód?
TIP. Használja a józan adattípusok és neveket, hogy képviselje a karakterek és vonalak.
Például ahelyett, hogy a változó a következő kódot:
Annak érdekében, hogy támogassa a többnyelvű alkalmazások (pl Unicode), akkor írj kódot, amely általánosabb módon.
A projekt beállításai Általános lapon van olyan paraméter, amely karakterkészlet milyen kódolást lefordítani a programot:

Ha az opció «használat Unicode karakterkészletet» írja TCHAR kerül adásba típusú wchar_t. Ha az opció «használat Multi-os karakterkészlet» majd TCHAR kerül adásba a char típus. Nyugodtan használja a típusok char és wchar_t, és a projekt beállítások nem befolyásolja a használatát ezeket a kulcsszavakat.
TCHAR meghatározása a következő:
_UNICODE makró engedélyezése, ha kiválaszt «használat Unicode karakterkészletet» majd írja TCHAR definiáljuk wchar_t. Ha kiválasztja a «használat Multi-os karakterkészlet» TCHAR definiáljuk char.
Ezen túlmenően, annak érdekében, hogy támogatást kapott több karakterkészletek egy közös kód alap, és képes támogatni számos nyelvi alkalmazások az adott funkciót (azaz makrók).
Ahelyett, hogy a strcpy, strlen, strcat (beleértve a védett funkció be előtaggal _s) vagy wcscpy, wcslen, wcscat (beleértve a védett beállítások), akkor jobb ha a _tcscpy funkció _tcslen, _tcscat.
Mint tudod strlen függvény leírása a következő:
És wcslen funkció leírása a következő:
Jobb, ha használni _tcslen, ami logikusan a következőképpen írja le:
WC egy széles karakter (Major Glyph). Ezért WCS funkciók lesznek a széles karakteres string (azaz a nagy karakterlánc) .Such módon _tcs azt jelenti _T karakterlánc. És mint tudjuk a húr előtaggal _T lehet char vagy wchar_t.
De a valóságban _tcslen (és egyéb funkciókat _tcs prefix) nem működik, akkor a makrókat. Egyszerűen le:
Így TCHAR nem olyan típusú, és add-on típusú char és wchar_t. Így lehetővé teszi, hogy válasszon a többnyelvű alkalmazás, vagy mindegy, az egyik nyelven.
Hogy miért ők le makrókkal, de nem a teljes funkció.
Az ok egyszerű: a könyvtár vagy a DLL lehet exportálni egy egyszerű függvény ugyanazt a nevet és a prototípus (Kivéve fogalom túlterhelés C ++).
Például, ha exportál egy funkciót:
Hogyan hívd ügyfél. Hogyan:
_TPrintChar varázslatosan lehet alakítani egy funkciót befogadó kétbájtos karakter érvként.
Ehhez, akkor nem két különböző funkciót:
És egy egyszerű makró will hide a különbség közöttük:
Az ügyfél egyszerűen meghívja a függvényt
Vegye figyelembe, hogy TCHAR és _TPrintChar most kompatibilis UNICODE vagy ANSI, valamint a változó és a funkcióparaméter CChar lesz összehasonlítható a típus char vagy wchar_t adatokat.
A makrók lehetővé teszi számunkra, hogy megkerüljék ezeket a nehézségeket, és lehetővé teszi számunkra, hogy használja az ANSI vagy UNICODE funkciók a karakterek és karakterláncok. A sok Windows-specifikus funkciókat ismertetjük ezen a módon, és a programozó csak egy funkciót (azaz egy makró), és ez jó volt.
Itt egy példa a SetWindowText:
Vannak csak néhány funkció, amelyben nincs ilyen makrók, és csak a utótag W vagy A. Egy példa erre a funkció ReadDirectoryChangesW, amelynek nincs megfelelője ANSI kódolással.
Mint tudja, az általunk használt dupla idézőjelek képviseletére szálakat. A string nyújtott ezen a módon ANSI-húr, minden karakter egy 1 byte. Itt egy példa:
Ez a felső sorban nem karakterlánc UNICODE, és nem alkalmas a több nyelv támogatása. Annak érdekében, hogy UNICODE húr akkor használja az előtag L.
Itt egy példa:
Helyezzük a bal első és kapsz egy UNICODE húr. Minden karakter (ismétlem, minden karakter) 2 bájt, beleértve az angol betűket, szóközt, számokat és null karaktert. Az adatok mennyisége Unicode karakterlánc mindig többszöröse a 2. bájt. Unicode karakterek string hossza 7 elfoglalják 14 bájt. Ha a Unicode karakterlánc 15 byte, akkor nem a megfelelő sort, és ez nem fog működni bármilyen összefüggésben.
Továbbá, a vonal lesz többszöröse méretű sizeof (TCHAR) bájtban.
Ha szüksége van egy beégetett kódot írhatunk kódot, mint ez:
Vonal előtag nélkül egy ANSI sztring előtaggal L Unicode karakterlánc, a húr előtaggal _T és TEXT függő összeállítás. Újra és TEXT _T makrók újra. Ezek meghatározása a következő:
## jel a kulcs (token) helyezze nyilatkozat, amely viszont _T ( «Unicode») L «Unicode», ahol a húr egy érv makrosa- hacsak _UNICODE meghatározva.
Ha _UNICODE nem határozta meg az _T ( «Unicode»), hogy azt a «Unicode». Key betét nyilatkozatot is létezett C nyelven, és ez nem egy konkrét dolgot kapcsolódó húrok kódolva VC ++.
Tájékoztatásul makrók lehet alkalmazni nem csak vonósokra, hanem a karakter. Például _T ( 'R') viszont L'R 'vagy, egy' R”. Azaz vagy a Unicode és ANSI karaktert.
Nem, és nem újra, akkor nem használhatja a makró átalakítani egy karakter vagy a Unicode és nem Unicode szöveget.
Az alábbi kód hibás:
_T sor (c); _T (str); Fordítsuk finom módban ANSI, _T (x) válik, X, és _T (c) együtt _T (str) átalakul egy c és str.
De ha építeni a projekt Unicode üzemmódban, a kód nélkül fordított:
Nem szeretnék, hogy stroke-ot okoz, az intelligencia, és hogy miért nem működik.
Több funkció átalakítására Mulbaytovyh húrok UNICODE, amit hamarosan megmondani.
Van egy fontos pont, szinte minden funkciót, hogy vesz egy karakterlánc vagy szimbólum, elsőbbséget élvez a Windows API, generikus néven az MSDN és másutt.
SetWindowTextA / W funkciót akkor minősül:
De mint tudjuk, ez csak SetWindowText makró, és attól függően, hogy a projekt beállításait kell tekinteni:
A könyvtár User32.dll, van 2 SetWindowTextA SetWindowTextW funkciók és exportált, vagyis nincs neve a generikus név.
Minden funkció, amely mind az ANSI és UNICODE változata, valójában csak UNICODE végrehajtását. Ez azt jelenti, hogy ha hívja SetWindowTextA saját kódját, átadva a paraméter ANSI húr - átalakítja ANSI Unicode SetWindowTextW.
A valódi munka (cím beállítás / / címke az ablak) teszi csak Unicode verzió!
Vegyünk egy másik példát, ami megkapja a szöveges ablakot GetWindowText.
Megadjuk GetWindowTextA átnyújtotta neki ANSI puffer a rendeltetési puffer.
GetWindowTextA első okozhat GetWindowTextW, esetleg elosztásának memória Unicode húrok (azaz egy tömb wchar_t).
Ezután konvertálja a Unicode ANSI húr az Ön számára.
Ezek ANSI és a Unicode átalakítás nem korlátozódik csak a GUI funkciókat, valamint fut a részhalmaza Windows API függvény, hogy vesz egy húr, és két lehetőség közül választhat.
Íme egy újabb példa az ilyen funkciók:
Ezért azt javasoljuk, hogy hívja közvetlenül a Unicode funkciókat.
Ez viszont azt jelenti, hogy mindig meg kell összpontosítani a szerelvény a Unicode verzió, hanem az ANSI változata a szerelvény, figyelembe véve azt a tényt, hogy hozzászokott a használatához ANSI húrok éve.
Igen, akkor mentse el és kap egy ANSI sztring, mint az írás egy fájlt, vagy küldjön azonnali üzeneteket programot chat. A funkciója konvertáló léteznek ilyen célokra.
Megjegyzés: Van egy másik típus leírása: WCHAR nevét - ez felel meg wchar_t.
TCHAR egy makrót nyilatkozat egyetlen karakter. Azt is egy tömböt a TCHAR. De mi van, ha azt szeretnénk, hogy leírja egy ilyen jellegű mutatót vagy const mutatót a karaktereket.
Itt egy példa:
Miután elolvasta a chips TCHAR, talán inkább használni. Vannak még jó alternatívát jelentenek húrok a kódban. Ehhez egyszerűen fordítsa Windows.h a projekt.
Megjegyzés: Ha a projekt magában windows.h (közvetlenül vagy közvetve), akkor nem kell tartalmaznia a TCHAR.H projektben.
Indítani felül a régi funkció, hogy könnyebben érthető. Példa funkció strlen.
Amely jelen lehet másképp.
Ahol LPCSTR le, mint:
LPCSTR így értik.
• LP - Hosszú Pointer (hosszú pointer)
• C - Constant (állandó)
• STR - String (karakterlánc)
Valójában ez LPCSTR (Long) mutató egy húr.
Változtassuk meg a strcpy összhangba az új stílus nevét típusok:
szTarget van LPSTR típus, anélkül, hogy a nyelvhasználat típusú S. LPSTR definíciója a következő:
Vegye figyelembe, hogy szSource van LPCSTR típus, hiszen a funkció strcpy nem módosítja a forrás puffer, így tegye a tulajdonság const. A visszaadott adat típusát nem konstans szöveget: LPSTR.
Ez a függvény a előtaggal str manipulálni ANSI húrok. De mi kell több két bájtos Unicode karakterláncok. Azok a nagy karakterek funkciója azonos.
Például, hogy kiszámítja a hossza karakterek nagy karakter (Unicode string), akkor használja wcslen:
wcslen függvény prototípusa a következő:
És a fenti kódot is képviselteti másképp:
Ahol LPCWSTR leírása a következő:
LPCWSTR lehet érteni a következő:
LP - Hosszú Pointer (hosszú nyelű)
C - állandó (konstans)
WSTR - Széles karakterlánc (nagy karaktersorozatot)
Hasonlóképpen strcpy egyenértékű wcscpy, a Unicode karakterláncok:
Ami lehet például:
Amennyiben ez nem állandó szTarget nagy tétel (LPWSTR) és konstans szSource nagy tétel.
Számos azonos funkciókat WCS-str-funkciókat. str-függvény használható egyszerű ANSI sorok és a WC-funkciók Unicode karakterláncok.
Bár már tájékoztatott, hogy kell használni a natív Unicode funkciók nemcsak ANSI vagy csak szintetizált TCHAR funkciót. Az ok egyszerű - az alkalmazás csak akkor Unicode-NYM, és nem érdekel, hogy mit sportiruyutsya ANSI. De a teljesség kedvéért megemlítem ezeket a közös kijelző (vetítés).
Kiszámítani a string hossza, akkor _tcslen funkció (makró).
Ami a következőképpen írja le:
Ahol LPCTSTR típus neve lehet érteni
LP - Hosszú Pointer (hosszú nyelű)
C - állandó (konstans)
T = TCHAR
STR = String (karakterlánc)
Attól függően, hogy a projekt beállítások LPCTSTR kerül bemutatásra a LPCSTR (ANSI) vagy LPCWSTR (Unicode).
Megjegyzés: strlen függvény, vagy wcslen _tcslen visszatér a karakterek száma soronként, hanem a bájtok számát.
Általános műveleti _tcscpy karakterlánc másolatát a következőképpen írja le:
Vagy általánosabb módon, mint például:
Meg tudja tippelni, hogy mit jelent LPTSTR))
Példák a felhasználásra.
Először ad egy példát a nem dolgozó kód:
Az ANSI összeszerelés, a kód lefordul sikeresen mert TCHAR egyfajta char, és a változó neve lesz egy sor char. Calling strlen a neve is fog működni.
Szóval Tegyük össze az azonos mellékelt UNICODE / _UNICODE (a projekt beállításait, válassza «Unicode használata Character Set»).
Most a fordító fog ez a típusú hiba:
És a programozók korrigálja a hibát, a következő módon:
És ez nem megbékíteni a fordító, mert a konverzió TCHAR * in TCHAR [7] lehetetlen. Ugyanaz a hiba akkor fordulhat elő, ha a beépített ANSI Unicode karakterláncok át a funkciót:
Sajnos (vagy szerencsére) ez a hiba lehet megfelelően korrigálni egy egyszerű működtetés típusú C.
És azt hiszem, hogy emeljék a saját élmény, amikor dolgozik mutató. Téved -ez a kód fog adni a rossz eredményt, és a legtöbb kapja az Access violation (access violation). Vet így például float-változtatható áttétel, amikor várható (logikusan) a szerkezet a 80 bájtot.
Húr «Saturn» sorozata 7 bájt:
De ha át ugyanazokat a bájtok wcslen, úgy véli, minden 2 bájt, mint egy karaktert. Ezért, az első 2 bájtot [97,83] kell tekinteni, mint egy szimbólum, amelynek értéke 24915 (97<<8 | 83). Это Unicode символ. И другие следующие символы рассматриваются как [117,116] и так далее.
Természetesen, ha nem felelt meg a kínai karakterek, de vet csinálni az Ön számára.
És ezért nagyon fontos tudni, hogy milyen típusú nem fog működni. Így az inicializálás az első sorban meg kell tennie a következőket:
Melyik fog sugározni a 7 vagy 14 bájt, attól függően, hogy fordításkor.
Hívjon wcslen kell:
A fenti példában a program kódot, azt használja a strlen, ami hibák a Unicode épít.
Itt egy példa a nem működő megoldás, hogy hozza a C nyelv típusok:
Unicode változó nevét szerelvények a mérete 14 bájt (7 karakter unicode, beleértve a null). Mivel a vonal
«Saturn» amely csak angol karakterek ábrázolni lehet ASCII kódolás, Unicode S betű kerül bemutatásra [83, 0]. A következő ASCII karaktereket képviseletében a nulla. Megjegyzés Most „S” karakter képviseli, mint egy 2 bájtos érték 83. A sor végére kerül képviseletében a 2 bájt, értéke 0.
Tehát, ha át egy stringet a strlen, az első karakter (vagyis az első byte) lenne ( „S” abban az esetben a „Szaturnusz”). De a következő karakter / bájt azonosítható a sor végére. Ezért strlen visszatér helytelen értéket 1.
Mint tudja, a Unicode karakterlánc tartalmazhat csak angol karaktereket, és az eredmény a strlen még bizonytalan.
Röviden vet nem fog működni.
Lesz, vagy jelent vonalat a megfelelő formában, vagy használja az ANSI konverziós funkció Unicode, kövesse és vissza.
Most, remélem érted a következő kódot:
Folytatva a témát. Ön valószínűleg látta néhány funkciót / módszereket kell átadniuk a karakterek száma, vagy visszaadja a karakterek számát. De GetCurrentDirectory, amely szükséges a továbbítja a karakterek száma, nem bájt.
például:
Másrészt, ha szüksége van a memóriát a kívánt karakterek száma meg kell osztania a megfelelő számú bájt. A C + +, akkor egyszerűen használja az üzemeltető új:
De ha használja memóriafoglalási funkciók, mint a malloc, LocalAlloc, GlobalAlloc stb meg kell adnia a bájtok számát!
Mint tudja, amire szükség van, hogy a leadott a visszatérési érték. A kifejezés érv malloc biztosítja, hogy osztja a szükséges bájtok számát - és kiosztja helyet a szükséges számú karaktert.
Összefoglalva, az enyhén pihenni az agyad. film idézet, „Egy nap az élet a rendszergazda”
Minden NG.