_tmain
nie istnieje w C++. main
ma.
_tmain
to rozszerzenie Microsoft.
main
jest, zgodnie ze standardem C++, punktem wejścia programu. Ma jeden z tych dwóch podpisów:
int main();
int main(int argc, char* argv[]);
Microsoft dodał wmain który zastępuje drugi podpis z tym:
int wmain(int argc, wchar_t* argv[]);
a potem, aby ułatwić przełączanie się między Unicode (UTF- 16) i ich wielobajtowy zestaw znaków, zdefiniowali _tmain
, który, jeśli jest włączony kod Unicode, jest skompilowany jako wmain
, a poza tym jako main
.
Jeśli chodzi o drugą część pytania, pierwsza część układanki jest taka, że główna funkcja jest błędna. wmain
powinien przyjąć argument wchar_t
, a nie char
. Ponieważ kompilator nie wymusza tego dla funkcji main
, otrzymujesz program, w którym tablica ciągów wchar_t
jest przekazywana do funkcji main
, co interpretuje je jako ciągi znaków.
Teraz, w UTF-16, zestaw znaków używany przez system Windows, gdy włączony jest kod Unicode, wszystkie znaki ASCII są reprezentowane jako para bajtów \0
, po których następuje wartość ASCII.
A ponieważ procesor x86 jest mało-endianowy, kolejność tych bajtów jest zamieniana, tak że wartość ASCII pojawia się jako pierwsza, po której następuje bajt zerowy.
A w łańcuchu znaków, w jaki sposób łańcuch zwykle się kończy? Tak, przez bajt zerowy. Zatem twój program widzi kilka ciągów, każdy o długości jednego bajtu.
W ogóle, masz trzy opcje, gdy robi programowania Windows:
- jawnie użyć Unicode (Call wmain, a dla każdej funkcji API systemu Windows, który bierze argumenty związane char, Call wersję funkcji
-W
.Zamiast CreateWindow, wywołaj CreateWindowW). I zamiast używać char
używać wchar_t
, i tak dalej
- Jawnie wyłączyć Unicode. Połącz główne i CreateWindowA i użyj
char
dla ciągów.
- Pozwól na oba. (wywołaj _tmain i CreateWindow, które rozdzielą na main/_tmain i CreateWindowA/CreateWindowW) i użyj TCHAR zamiast char/wchar_t.
To samo odnosi się do typów łańcuchowych zdefiniowanych przez windows.h: LPCTSTR postanawia obu LPCSTR lub LPCWSTR, i dla każdego innego rodzaju, który zawiera char lub wchar_t, A -T- zawsze istnieje wersja, która może być używana zamiast.
Należy pamiętać, że wszystko to dotyczy firmy Microsoft. TCHAR nie jest standardowym typem C++, jest to makro zdefiniowane w windows.h. wmain i _tmain są również zdefiniowane tylko przez Microsoft.
Zastanawiam się, czy zapewniają one również tcout? aby można było wykonać tcout << argv [n]; i rozwiązuje się cout w Ansi i wcout w trybie Unicode? Podejrzewam, że może mu się przydać w tej sytuacji. i +1 oczywiście, fajna odpowiedź :) –
Jaką wadą byłoby wyłączanie UNICODE? – joshcomley
@Johannes Schaub - litb: AFAIK, nie zapewniają tcout (nawet jeśli zapewniają cout i wcout). W Visual C++ 2003 musiałem zdefiniować jeden, a także zdefiniować i/lub typedef wszystkie inne symbole związane z STL chciałem użyć TCHAR. Nie wiem jednak o Visual C++ 2008 lub 2010. – paercebal