Ich bin neu in der Windows-Programmierung und nachdem ich das Petzold-Buch gelesen habe, frage ich mich:
Ist es immer noch eine gute Praxis, den TCHAR
Typ und die _T()
Funktion zum Deklarieren von Zeichenfolgen zu verwenden, oder sollte ich nur die Zeichenfolgen wchar_t
und L""
in neuem Code verwenden?
Ich werde nur auf Windows 2000 und höher abzielen und mein Code wird von Anfang an i18n sein.
Die kurze Antwort: NEIN .
Wie alle anderen bereits geschrieben haben, verwenden viele Programmierer immer noch TCHARs und die entsprechenden Funktionen. Meiner bescheidenen Meinung nach war das ganze Konzept eine schlechte Idee . Die UTF-16- Zeichenfolgenverarbeitung unterscheidet sich stark von der einfachen ASCII / MBCS-Zeichenfolgenverarbeitung. Wenn Sie mit beiden dieselben Algorithmen / Funktionen verwenden (darauf basiert die TCHAR-Idee!), Erhalten Sie in der UTF-16-Version eine sehr schlechte Leistung, wenn Sie ein wenig mehr als nur eine einfache Zeichenfolgenverkettung ausführen (z Parsen etc.). Der Hauptgrund sind Surrogate .
Mit der einzigen Ausnahme, wenn Sie Ihre Anwendung wirklich für ein System kompilieren müssen, das Unicode nicht unterstützt, sehe ich keinen Grund, dieses Gepäck aus der Vergangenheit in einer neuen Anwendung zu verwenden.
quelle
TCHAR
nicht mehr verwendet werden sollte, aber ich bin nicht der Meinung, dass dies eine schlechte Idee war. Ich denke auch, dass Sie überall explizit sein sollten , wenn Sie sich dafür entscheiden, explizit zu sein, anstatt zu verwenden . Dh auch keine Funktionen mit / (wie ) in ihrer Deklaration verwenden. Einfach ausgedrückt: Seien Sie konsequent. +1, immer noch.TCHAR
TCHAR
_TCHAR
_tmain
TCHAR
ursprünglich eingeführt wurde: Um die Entwicklung von Code für Windows 9x- und Windows NT-basierte Windows-Versionen zu vereinfachen. Zu dieser Zeit war die UTF-16-Implementierung von Windows NT UCS-2, und die Algorithmen für das Parsen / Manipulieren von Zeichenfolgen waren identisch. Es gab keine Leihmütter. Und selbst bei Ersatzzeichen sind die Algorithmen für DBCS (die einzige unterstützte MBCS-Codierung für Windows) und UTF-16 identisch: Bei beiden Codierungen besteht ein Codepunkt aus einer oder zwei Codeeinheiten.Ich muss Sascha zustimmen. Die zugrunde liegende Prämisse von
TCHAR
/_T()
/ etc. ist, dass Sie eine "ANSI" -basierte Anwendung schreiben und ihr dann auf magische Weise Unicode-Unterstützung geben können, indem Sie ein Makro definieren. Dies basiert jedoch auf mehreren schlechten Annahmen:Dass Sie aktiv sowohl MBCS- als auch Unicode-Versionen Ihrer Software erstellen
Andernfalls Sie wird nach oben rutschen und verwenden gewöhnliche
char*
Strings in vielen Orten.Dass Sie keinen Nicht-ASCII-Backslash verwenden, wird in _T ("...") - Literalen maskiert
Sofern Ihre "ANSI" -Codierung nicht ISO-8859-1 ist, repräsentieren das Ergebnis
char*
und diewchar_t*
Literale nicht dieselben Zeichen.Diese UTF-16-Zeichenfolgen werden genau wie "ANSI" -Strings verwendet
Sie sind nicht. Unicode führt verschiedene Konzepte ein, die in den meisten älteren Zeichenkodierungen nicht vorhanden sind. Surrogate. Charaktere kombinieren. Normalisierung. Bedingte und sprachempfindliche Gehäuseregeln.
Und vielleicht am wichtigsten ist die Tatsache, dass UTF-16 selten auf der Festplatte gespeichert oder über das Internet gesendet wird: UTF-8 wird für die externe Darstellung bevorzugt.
Dass Ihre Anwendung das Internet nicht nutzt
(Nun, dies kann eine gültige Annahme für Ihre Software sein, aber ...)
Das Web läuft auf UTF-8 und einer Vielzahl seltener Codierungen . Das
TCHAR
Konzept erkennt nur zwei: "ANSI" (das kann nicht UTF-8 sein ) und "Unicode" (UTF-16). Es kann nützlich sein, um Ihre Windows-API-Aufrufe Unicode-fähig zu machen, aber es ist verdammt nutzlos, um Ihre Web- und E-Mail-Apps Unicode-fähig zu machen.Dass Sie keine Nicht-Microsoft-Bibliotheken verwenden
Niemand sonst benutzt
TCHAR
. Poco verwendetstd::string
und UTF-8. SQLite hat UTF-8- und UTF-16-Versionen seiner API, aber neinTCHAR
.TCHAR
ist nicht einmal in der Standardbibliothek, also neinstd::tcout
sei denn, Sie möchten es selbst definieren.Was ich anstelle von TCHAR empfehle
Vergessen Sie, dass "ANSI" -Codierungen vorhanden sind, außer wenn Sie eine Datei lesen müssen, die nicht für UTF-8 gültig ist. Vergiss es
TCHAR
auch. Rufen Sie immer die "W" -Version der Windows-API-Funktionen auf.#define _UNICODE
Nur um sicherzustellen, dass Sie nicht versehentlich eine "A" -Funktion aufrufen.Verwenden Sie immer UTF-Codierungen für Zeichenfolgen: UTF-8 für
char
Zeichenfolgen und UTF-16 (unter Windows) oder UTF-32 (auf Unix-ähnlichen Systemen) fürwchar_t
Zeichenfolgen.typedef
UTF16
undUTF32
Zeichentypen, um Plattformunterschiede zu vermeiden.quelle
#define _UNICODE
auch jetzt noch gewartet werden muss . Ende der Übertragung :)_UNICODE
Steuert, wie die generischen Textzuordnungen in der CRT aufgelöst werden. Wenn Sie die ANSI-Version einer Windows-API nicht aufrufen möchten, müssen Sie definierenUNICODE
.Wenn Sie sich fragen, ob es noch in der Praxis ist, dann ja - es wird immer noch ziemlich oft verwendet. Niemand wird Ihren Code lustig ansehen, wenn er TCHAR und _T ("") verwendet. Das Projekt, an dem ich gerade arbeite, konvertiert von ANSI zu Unicode - und wir gehen den tragbaren Weg (TCHAR).
Jedoch...
Meine Stimme wäre, alle tragbaren ANSI / UNICODE-Makros (TCHAR, _T ("") und alle _tXXXXXX-Aufrufe usw.) zu vergessen und einfach überall Unicode anzunehmen. Ich sehe keinen Sinn darin, portabel zu sein, wenn Sie nie eine ANSI-Version benötigen. Ich würde alle breiten Zeichenfunktionen und -typen direkt verwenden. Stellen Sie alle Zeichenfolgenliterale mit einem L vor.
quelle
In dem Artikel Einführung in die Windows-Programmierung auf MSDN heißt es
Ich würde mich an
wchar_t
und haltenL""
.quelle
Ich möchte einen anderen Ansatz vorschlagen (keiner der beiden).
Verwenden Sie zusammenfassend char * und std :: string unter der Annahme einer UTF-8-Codierung und führen Sie die Konvertierungen in UTF-16 nur durch, wenn Sie API-Funktionen einschließen.
Weitere Informationen und Begründungen für diesen Ansatz in Windows-Programmen finden Sie unter http://www.utf8everywhere.org .
quelle
TCHAR
IchWCHAR
könnte für einige Legacy-Projekte ausreichen. Aber für neue Anwendungen würde ich NEIN sagen .Alle dieser
TCHAR
/WCHAR
Sachen sind da , weil die historischen Gründe.TCHAR
bietet eine scheinbar saubere Möglichkeit (Verkleidung), zwischen ANSI-Textcodierung (MBCS) und Unicode-Textcodierung (UTF-16) zu wechseln. In der Vergangenheit hatten die Menschen kein Verständnis für die Anzahl der Zeichen aller Sprachen der Welt. Sie nahmen an, dass 2 Bytes ausreichen, um alle Zeichen darzustellen, und daher ein Zeichencodierungsschema mit fester Länge verwendenWCHAR
. Dies gilt jedoch nicht mehr nach der Veröffentlichung von Unicode 2.0 im Jahr 1996 .Das heißt: Unabhängig davon, was Sie in
CHAR
/WCHAR
/ verwendenTCHAR
, sollte der Textverarbeitungsteil in Ihrem Programm in der Lage sein, Zeichen variabler Länge zu verarbeiten für die Internationalisierung zu verarbeiten.Sie müssen also tatsächlich mehr tun, als eine aus
CHAR
/WCHAR
/TCHAR
für die Programmierung in Windows auszuwählen:WCHAR
. Da es auf diese Weise einfacher ist, mit WinAPI mit Unicode-Unterstützung zu arbeiten.Weitere Informationen finden Sie auf dieser wunderbaren Website: http://utf8everywhere.org/
quelle
Ja absolut; Zumindest für das _T-Makro. Ich bin mir allerdings nicht so sicher, was die Charaktere angeht.
Der Grund dafür ist, WinCE oder andere nicht standardmäßige Windows-Plattformen besser zu unterstützen. Wenn Sie zu 100% sicher sind, dass Ihr Code auf NT verbleibt, können Sie wahrscheinlich nur reguläre C-String-Deklarationen verwenden. Es ist jedoch am besten, sich dem flexibleren Ansatz zuzuwenden, da es viel einfacher ist, dieses Makro auf einer Nicht-Windows-Plattform zu definieren, als Tausende von Codezeilen zu durchlaufen und es überall hinzuzufügen, falls Sie eine Bibliothek portieren müssen zu Windows Mobile.
quelle
IMHO, wenn Ihr Code TCHARs enthält, arbeiten Sie auf der falschen Abstraktionsebene.
Verwenden Sie was auch immer String - Typ ist für Sie am bequemsten , wenn sie mit Textverarbeitung zu tun - das wird hoffentlich etwas unterstützt Unicode sein, aber das ist bei Ihnen. Führen Sie die Konvertierung nach Bedarf an den Grenzen der Betriebssystem-API durch.
Erstellen Sie beim Umgang mit Dateipfaden Ihren eigenen benutzerdefinierten Typ, anstatt Zeichenfolgen zu verwenden. Dies ermöglicht Ihnen betriebssystemunabhängige Pfadtrennzeichen, bietet Ihnen eine einfachere Schnittstelle zum Codieren als manuelle Verkettung und Aufteilung von Zeichenfolgen und ist viel einfacher an verschiedene Betriebssysteme anzupassen (ansi, ucs-2, utf-8, was auch immer). .
quelle
Die einzigen Gründe, warum ich etwas anderes als das explizite WCHAR verwende, sind Portabilität und Effizienz.
Wenn Sie Ihre endgültige ausführbare Datei so klein wie möglich halten möchten, verwenden Sie char.
Wenn Sie sich nicht für die RAM-Nutzung interessieren und möchten, dass die Internationalisierung so einfach wie die einfache Übersetzung ist, verwenden Sie WCHAR.
Wenn Sie Ihren Code flexibel gestalten möchten, verwenden Sie TCHAR.
Wenn Sie nur die lateinischen Zeichen verwenden möchten, können Sie auch die ASCII / MBCS-Zeichenfolgen verwenden, damit Ihr Benutzer nicht so viel RAM benötigt.
Sparen Sie sich für Leute, die "i18n von Anfang an" sind, den Quellcode-Speicherplatz und verwenden Sie einfach alle Unicode-Funktionen.
quelle
Nur zu einer alten Frage hinzufügen:
NEIN
Starten Sie ein neues CLR C ++ - Projekt in VS2010. Microsoft selbst verwenden "
L"Hello World"
, sagte Nuff.quelle
C
undC++
. Antworten können jederzeit von den jeweiligen Autoren gelöscht werden. Dies wäre ein guter Zeitpunkt, um diese Bestimmung zu nutzen.TCHAR
haben eine neue Bedeutung zu portieren vonWCHAR
nachCHAR
.https://docs.microsoft.com/en-us/windows/uwp/design/globalizing/use-utf8-code-page
quelle