Czy TCHAR jest nadal aktualny?

Jestem nowy w programowaniu Windows i po przeczytaniu książki Petzold zastanawiam się:

Czy nadal dobrą praktyką jest używanie typu TCHAR i funkcji _T() do deklarowania łańcuchów znaków, czy też po prostu powinienem używać łańcuchów wchar_t i L"" w nowym kodzie?

Będę kierować tylko Windows 2000 i do góry, a mój kod będzie i18n od początku.

Author: Peter Mortensen, 2008-10-24

12 answers

Nadal używałbym składni TCHAR, gdybym dziś robił nowy projekt. Nie ma dużej praktycznej różnicy między używaniem go a składnią WCHAR, a ja wolę kod, który jest jednoznaczny w tym, jaki jest typ znaków. Ponieważ większość funkcji API i obiektów pomocniczych przyjmuje / używa typów TCHAR( np.: CString), po prostu warto z nich korzystać. Plus to daje elastyczność, jeśli zdecydujesz się użyć kodu w aplikacji ASCII w pewnym momencie, lub jeśli Windows kiedykolwiek ewoluuje do Unicode32, itp.

Jeśli zdecydujesz aby przejść trasę WCHAR, powiedziałbym wyraźnie. Oznacza to, że użyj CStringW zamiast CString, i rzucanie makr podczas konwersji do TCHAR (NP: CW2CT).

To i tak moje zdanie.

 15
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 23:21:07

Krótka odpowiedź: NIE .

Jak wszyscy inni już pisali, wielu programistów nadal używa Tcharów i odpowiadających im funkcji. Moim skromnym zdaniem cała koncepcja była złym pomysłem . UTF-16 przetwarzanie łańcuchów różni się znacznie od zwykłego przetwarzania łańcuchów ASCII/MBCS. Jeśli używasz tych samych algorytmów/funkcji z obydwoma (na tym opiera się idea TCHAR!), dostajesz bardzo złą wydajność na wersji UTF-16 jeśli robisz trochę nieco więcej niż zwykła konkatenacja łańcuchów (np. parsowanie itp.). Głównym powodem są Surogaci .

Z jedynym wyjątkiem, kiedy Naprawdę musisz skompilować swoją aplikację dla systemu, który nie obsługuje Unicode, nie widzę powodu, aby używać tego bagażu z przeszłości w nowej aplikacji.

 91
Author: Sascha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 16:14:03

Muszę się zgodzić z Saschą. Podstawowym założeniem TCHAR / _T() / itd. jest to, że można napisać aplikację "ANSI", a następnie magicznie dać mu wsparcie Unicode, definiując makro. Ale opiera się to na kilku złych założeniach: {]}

Że aktywnie budujesz zarówno wersje MBCS, jak i Unicode swojego oprogramowania

W przeciwnym razie, potkniesz się i użyjesz zwykłych char* ciągów w wielu miejscach.

Że nie używasz Nie-ASCII backslash ucieka w _T ("...") literały

O ile twoje kodowanie "ANSI" nie będzie zgodne z ISO-8859-1, powstałe literały char* i wchar_t* nie będą reprezentować tych samych znaków.

Że struny UTF-16 są używane podobnie jak struny "ANSI"

Nie są. Unicode wprowadza kilka pojęć, które nie istnieją w większości starszych kodowań znaków. Surogatki. Łączenie znaków. Normalizacja. Obudowa warunkowa i językowa Zasady.

I być może najważniejsze, fakt, że UTF-16 jest rzadko zapisywany na dysku lub wysyłany przez Internet: UTF-8 jest preferowany do reprezentacji zewnętrznej.

Że Twoja aplikacja nie korzysta z Internetu

(może to być słuszne założenie dla twojego oprogramowania, ale...)

Sieć działa na UTF-8 i mnóstwo rzadszych kodowań . TCHAR pojęcie rozpoznaje tylko dwa: "ANSI" (które nie można być UTF-8) i "Unicode" (UTF-16). Może być przydatny do wykonywania połączeń API systemu Windows Unicode, ale jest cholernie bezużyteczny do tworzenia aplikacji internetowych i e-mail Unicode.

Że nie używasz bibliotek innych niż Microsoft

Nikt inny nie używa TCHAR. Poco używa std::string i UTF-8. SQLite mA wersje UTF-8 i UTF-16 swojego API, ale nie TCHAR. TCHAR nie jest nawet w bibliotece standardowej, więc nie std::tcout, chyba że chcesz zdefiniuj to sam.

Co polecam zamiast TCHAR

Zapomnij, że istnieją kodowania "ANSI", z wyjątkiem sytuacji, gdy musisz odczytać plik, który nie jest prawidłowym UTF-8. Zapomnij o TCHAR też. Zawsze wywołaj wersję" W " funkcji Windows API. #define _UNICODE aby upewnić się, że nie przypadkowo wywołasz funkcji "A".

Zawsze używaj kodowania UTF dla łańcuchów: UTF-8 dla łańcuchów char i UTF-16 (W Windows) lub UTF-32 (W systemach uniksowych) dla łańcuchów wchar_t. typedef UTF16 i UTF32 typów znaków, aby uniknąć różnic między platformami.

 81
Author: dan04,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:11

Jeśli zastanawiasz się, czy nadal jest w praktyce, to tak - nadal jest używany dość często. Nikt nie spojrzy na Twój kod śmiesznie, jeśli używa TCHAR i _T (""). Projekt, nad którym teraz pracuję, konwertuje z ANSI na unicode - i idziemy trasą portable (TCHAR).

jednak...

Moim głosem byłoby zapomnieć o wszystkich przenośnych makrach ANSI / UNICODE (TCHAR, _T (" " ) i wszystkich wywołaniach _tXXXXXX itp...) i zakładaj Unicode wszędzie. Naprawdę nie widzę sens bycia przenośnym, jeśli nigdy nie będziesz potrzebował wersji ANSI. Użyłbym wszystkich szerokich funkcji i typów znaków bezpośrednio. Preprend wszystkie literały ciągu z l.

 18
Author: Aardvark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-24 17:29:16

Artykuł Wprowadzenie do programowania Windows na MSDN mówi

Nowe aplikacje powinny zawsze wywoływać wersje Unicode (API).

Makra TEXT i TCHAR są dziś mniej przydatne, ponieważ wszystkie aplikacje powinny używać Unicode.

Trzymałbym się wchar_t i L"".

 11
Author: Steven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Chciałbym zaproponować inne podejście(żadne z nich).

Aby podsumować, użyj char * i std:: string, zakładając kodowanie UTF-8, i wykonaj konwersje do UTF-16 Tylko podczas owijania funkcji API.

Więcej informacji i uzasadnienie takiego podejścia w programach Windows można znaleźć w http://www.utf8everywhere.org .

 11
Author: Pavel Radzivilovsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-01 06:17:43

TCHAR/WCHAR może wystarczyć na niektóre starsze projekty. Ale dla nowych aplikacji, powiedziałbym Nie .

Wszystkie te TCHAR/WCHAR rzeczy są tam z powodów historycznych. TCHAR zapewnia prosty sposób (disguise) przełączania się między kodowaniem tekstu ANSI (MBCS) a kodowaniem tekstu Unicode (UTF-16). W przeszłości ludzie nie rozumieli liczby znaków wszystkich języków na świecie. Zakładali, że 2 bajty wystarczą do reprezentowania wszystkich znaków i w ten sposób mający schemat kodowania znaków o stałej długości za pomocą WCHAR. Jednak nie jest to już prawdą po wydaniu Unicode 2.0 w 1996.

To znaczy: Bez względu na to, którego używasz w CHAR/WCHAR/TCHAR, część przetwarzania tekstu w programie powinna być w stanie obsługiwać znaki o zmiennej długości w celu internacjonalizacji.

Więc faktycznie trzeba zrobić więcej niż wybór jednego z CHAR/WCHAR/TCHAR do programowania w systemie Windows:

  1. jeśli Twoja aplikacja jest mała i nie wymaga przetwarzania tekstu (tzn. tylko przekazywania ciągu tekstowego jako argumentów), a następnie trzymaj się WCHAR. Ponieważ łatwiej jest w ten sposób pracować z WinAPI z obsługą Unicode.
  2. W Przeciwnym Razie sugerowałbym użycie UTF - 8 jako wewnętrznego kodowania i przechowywanie tekstów w łańcuchach znaków lub std:: string. I ukryj je w UTF-16 podczas wywoływania WinAPI. UTF-8 jest teraz dominującym kodowaniem i istnieje wiele przydatnych bibliotek i narzędzi do przetwarzania UTF-8 struny.

Sprawdź tę wspaniałą stronę internetową, aby dowiedzieć się więcej: http://utf8everywhere.org/

 8
Author: LeOpArD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 14:11:46

Tak, absolutnie; przynajmniej dla makra _T. Ale nie jestem pewien, co do szeroko pojętego charakteru.

Powodem jest lepsza obsługa WinCE lub innych niestandardowych platform Windows. Jeśli jesteś w 100% pewien, że Twój kod pozostanie na NT, prawdopodobnie możesz po prostu użyć zwykłych deklaracji C-string. Jednak najlepiej jest skłaniać się ku bardziej elastycznemu podejściu, ponieważ znacznie łatwiej jest # zdefiniować to makro na platformie innej niż windows w porównaniu do przechodzenia przez tysiące linii kodu i dodawanie go wszędzie na wypadek, gdybyś musiał przenieść jakąś bibliotekę do windows mobile.

 4
Author: Nik Reiman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-24 17:07:18

IMHO, jeśli w Twoim kodzie są Tchary, to pracujesz na złym poziomie abstrakcji.

Użyj cokolwiek string type jest najwygodniejsze dla ciebie, gdy masz do czynienia z przetwarzaniem tekstu - miejmy nadzieję, że będzie to coś wspierającego unicode, ale to zależy od Ciebie. Wykonaj konwersję w granicach API OS w razie potrzeby.

Gdy mamy do czynienia ze ścieżkami plików, należy utworzyć własny, niestandardowy typ zamiast używać ciągów. Pozwoli to na separatory ścieżek niezależne od systemu operacyjnego, da łatwiejszy interfejs do kodowania niż ręczne łączenie i dzielenie łańcuchów, i będzie o wiele łatwiejsze do dostosowania do różnych systemów operacyjnych (ansi, UCS-2, utf-8, cokolwiek).

 2
Author: snemarch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-08-26 07:31:27

Jedyne powody, dla których widzę, aby używać czegokolwiek innego niż jawny WCHAR, to przenośność i wydajność.

Jeśli chcesz, aby twój finalny plik wykonywalny był jak najmniejszy, użyj char.

Jeśli nie zależy ci na użyciu pamięci RAM i chcesz, aby Internacjonalizacja była tak łatwa, jak proste tłumaczenie, użyj WCHAR.

Jeśli chcesz uelastycznić swój kod, użyj TCHAR.

Jeśli planujesz używać tylko znaków łacińskich, równie dobrze możesz użyć ciągów ASCII / MBCS, aby twój użytkownik nie potrzebuje tyle pamięci RAM.

Dla osób, które są "i18n od początku", oszczędź sobie miejsca na kod źródłowy i po prostu użyj wszystkich funkcji Unicode.

 2
Author: Trololol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 03:24:37

Dodaję do starego pytania:

NIE

Rozpocznij nowy projekt CLR C++ w VS2010. Microsoft używa L"Hello World",

 -1
Author: kizzx2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-25 12:45:09

TCHAR mają nowe znaczenie dla portu z WCHAR do CHAR.

Https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page

Ostatnie Wydania systemu Windows 10 używały strony kodu ANSI i-A API jako sposób wprowadzenia obsługi UTF-8 do aplikacji. Jeżeli kod ANSI strona jest skonfigurowana dla UTF-8, - A API działają w UTF-8.

 -1
Author: OwnageIsMagic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-07 21:18:23