W podobnych słowach, gdzie oba są wprowadzane do kodu źródłowego z tym samym kodowaniem (UTF-8), a ustawienia regionalne są poprawne, czy jest jakiś praktyczna różnica między nimi?Drukowanie ciągów UTF-8 z literami printf - szeroki kontra wielobajtowy
printf("ο Δικαιοπολις εν αγρω εστιν\n");
printf("%ls", L"ο Δικαιοπολις εν αγρω εστιν\n");
W związku z tym czy istnieje jakikolwiek powód, aby preferować jeden nad drugim podczas wykonywania wydruków? Wyobrażam sobie, że druga gra trochę gorzej, ale czy ma jakąś przewagę (lub wadę) nad literałem wielobajtowym?
EDYCJA: Nie ma problemów z drukowaniem tych ciągów. Ale nie używam funkcji szerokich ciągów znaków, ponieważ chcę również móc używać printf
itd. Pytanie brzmi więc, czy te sposoby drukowania są inne (biorąc pod uwagę sytuację opisaną powyżej), a jeśli tak, to czy druga ma jakąś przewagę?
EDIT2: Po komentarze poniżej, teraz wiem, że ten program działa - co moim zdaniem nie było to możliwe:
int main()
{
setlocale(LC_ALL, "");
wprintf(L"ο Δικαιοπολις εν αγρω εστιν\n"); // wide output
freopen(NULL, "w", stdout); // lets me switch
printf("ο Δικαιοπολις εν αγρω εστιν\n"); // byte output
}
Edit3: Zrobiłem kilka dalszych badań przez patrząc na to, co się dzieje z tymi dwoma typami. Prostszy ciąg:
wchar_t *wides = L"£100 π";
char *mbs = "£100 π";
Kompilator generuje inny kod. Szeroki ciąg jest:
.string "\243"
.string ""
.string ""
.string "1"
.string ""
.string ""
.string "0"
.string ""
.string ""
.string "0"
.string ""
.string ""
.string " "
.string ""
.string ""
.string "\300\003"
.string ""
.string ""
.string ""
.string ""
.string ""
Podczas gdy druga jest:
.string "\302\243100 \317\200"
i patrząc na kodowania Unicode, drugi to zwykły UTF-8. Szeroka reprezentacja znaków to UTF-32. Rozumiem, że będzie to zależne od wdrożenia.
Czyli szersza reprezentacja znakowa literałów jest bardziej przenośna? Mój system nie będzie bezpośrednio drukować kodowań UTF-16/UTF-32, więc jest automatycznie konwertowany na UTF-8 dla wyjścia.
Mówiłeś oba przykłady są wprowadzane z UTF-8. W drugim wierszu przykładowym, jeśli ten tekst jest w rzeczywistości UTF-8, a nie szerokim kodowaniem, prawdopodobnie nie powinieneś mieć prefiksu L, dlatego użyjesz '% s' zamiast'% ls'. Albo nadal nie rozumiem tego pytania. –
@AdrianMcCarthy - oba ciągi w kodzie źródłowym to UTF-8, tak. Ale literał łańcuchowy jest zawsze wielobajtowy - "Literał ciągu znaków jest sekwencją zero lub więcej znaków wielobajtowych zamkniętych w podwójnych cudzysłowach, jak w" xyz ". Szeroki ciąg literału jest taki sam, z wyjątkiem prefiksowanym literą L. " od normy. – teppic
AFAIR, wszystkie znaki spoza podstawowego zestawu znaków źródłowych (który jest * podzbiorem * US-ASCII-7) wywołują zachowanie zdefiniowane przez implementację, tzn. Wszystko tutaj omówione jest efektywnie zależne od używanego kompilatora. Jeśli naprawdę chcesz grać bezpiecznie (i przenośnie), musiałbyś uciekać się do \ u ... i \ U ... – DevSolar