Jak utworzyć literał ciągu znaków UTF-8 w programie Visual C ++ 2008
W VC ++ 2003 mogłem po prostu zapisać oryginalny plik jako UTF-8 i wszystkie napisy zostały użyte tak, jak są. Innymi słowy, poniższy kod wyprowadzi wiersze bez zmian do konsoli. Jeśli oryginalny plik został zapisany jako UTF-8, wyjście będzie miało format UTF-8.
printf("Chinese (Traditional)");
printf("中国語 (繁体)");
printf("중국어 (번체)");
printf("Chinês (Tradicional)");
Zapisałem plik w formacie UTF-8 z BOM UTF-8. Jednak kompilacja z VC2008 daje:
warning C4566: character represented by universal-character-name '\uC911'
cannot be represented in the current code page (932)
warning C4566: character represented by universal-character-name '\uAD6D'
cannot be represented in the current code page (932)
etc.
Symbole powodujące te ostrzeżenia są uszkodzone. Te, które pasują do ustawień regionalnych (w tym przypadku 932 = japońskie) są konwertowane na kodowanie regionalne, tj. Shift-JIS.
Nie mogę znaleźć sposobu, aby VC ++ 2008 skompilował to za mnie. Zauważ, że nie ma znaczenia, jakiego języka używam w pliku źródłowym. Wygląda na to, że nie ma ustawienia regionalnego, które mówi „Wiem, co robię, więc nie zmieniaj moich literałów tekstowych”. W szczególności nie działa bezużyteczne pseudo-locale UTF-8.
#pragma setlocale(".65001")
=> error C2175: '.65001' : invalid locale
Jak „C”:
#pragma setlocale("C")
=> see warnings above (in particular locale is still 932)
Wygląda na to, że VC2008 wymusza na wszystkich znakach określone (lub domyślne) ustawienie regionalne, a tym ustawieniem nie może być UTF-8. Nie chcę zmieniać pliku tak, aby używał łańcuchów zmiany znaczenia, takich jak „\ xbf \ x11 ...”, ponieważ to samo źródło jest kompilowane przy użyciu gcc, który może bardzo dobrze radzić sobie z plikami UTF-8.
Czy istnieje sposób, aby określić, że kompilacja pliku źródłowego powinna pozostawić nienaruszone literały ciągów?
Aby określić inaczej, których flag kompilacji mogę użyć do wskazania wstecznej kompatybilności z VC2003 podczas kompilowania pliku źródłowego, to znaczy nie zmieniaj literałów łańcuchowych, używaj ich bajt po bajcie w obecnej postaci.
Aktualizacja
Dzięki za sugestie, ale chcę uniknąć wchar. Ponieważ ta aplikacja obsługuje wyłącznie łańcuchy UTF-8, użycie wchar wymagałoby konwersji wszystkich łańcuchów z powrotem na UTF-8, co powinno być niepotrzebne. Wszystkie dane wejściowe, wyjściowe i wewnętrzne przetwarzanie są w UTF-8. Jest to prosta aplikacja, która działa świetnie zarówno w systemie Linux, jak i po skompilowaniu z VC2003. Chcę móc skompilować tę samą aplikację z VC2008 i uruchomić ją.
W tym celu potrzebuję VC2008, aby nie próbować konwertować go do ustawień lokalnych mojej maszyny lokalnej (japoński, 932). Chcę, aby VC2008 był wstecznie kompatybilny z VC2003. Potrzebuję opcji ustawień regionalnych lub kompilatora, która mówi, że ciągi znaków są używane jako takie, zasadniczo jako nieprzezroczyste tablice znaków lub jako UTF-8. Wygląda na to, że utknąłem z VC2003 i gcc, chociaż VC2008 stara się być w tym przypadku zbyt sprytny.
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
17 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Pomyślałem, że nie ma na to żadnego gwarantowanego sposobu. Rozwiązanie, które prezentuję poniżej, działa dla angielskiej wersji VC2003, ale zawodzi podczas kompilacji z japońską wersją VC2003 (a może jest to japoński system operacyjny). W każdym razie nie możesz polegać na jego pracy. Zauważ, że nawet zadeklarowanie wszystkiego jako "" łańcuchów L nie działało (i było bolesne w gcc, jak opisano poniżej).
Zamiast tego uważam, że wystarczy ugryźć kulę i przenieść cały tekst do pliku danych i stamtąd go załadować. Teraz przechowuję tekst w plikach INI i uzyskuję do niego dostęp za pośrednictwem
SimpleIni
http://code.jellycan.com/simpleini/
(wieloplatformowa biblioteka plików INI). Przynajmniej jest gwarancja, że to działa, ponieważ cały tekst jest poza programem.
Oryginalny:
Sam odpowiadam na to pytanie, ponieważ tylko Evan zdawał się rozwiązywać problem. Odpowiedzi na temat tego, czym jest Unicode i jak używać wchar_t, są nieistotne w tym problemie, ponieważ nie dotyczą one internacjonalizacji ani niezrozumienia kodowania znaków Unicode. Doceniam twoją próbę pomocy, ale przepraszam, jeśli nie wyraziłem się wystarczająco jasno.
Problem w tym, że mam pliki źródłowe, które trzeba skompilować na różnych platformach i kompilatorach. Program przetwarza UTF-8. Nie obchodzi go żadne inne kodowanie. Chcę mieć literały ciągów w UTF-8, tak jak obecnie działa z gcc i vc2003. Jak mam to zrobić z VC2008? (tj. rozwiązanie kompatybilne wstecz).
Oto co znalazłem:
gcc (v4.3.2 20081105):
vc2003:
vc2005+:
Zatem prosta odpowiedź jest taka, że w tym konkretnym celu VC2005 + jest uszkodzony i nie zapewnia ścieżki kompilacji kompatybilnej wstecz. Jedynym sposobem na pobranie ciągów Unicode do skompilowanego programu jest użycie UTF-8 + BOM + wchar, co oznacza, że muszę przekonwertować wszystkie ciągi z powrotem na UTF-8 w momencie użycia.
Nie ma prostej międzyplatformowej metody konwersji wchar do UTF-8, na przykład, jaki rozmiar i kodowanie jest w wchar? W systemie Windows UTF-16. Na innych platformach? Ona się zmienia. Oswajać
z projektem
http://icu-project.org/docs/pa ... .html
OIOM trochę szczegółów.
W końcu zdecydowałem, że uniknę kosztów konwersji na wszystkich kompilatorach z wyjątkiem vc2005 + z kodem źródłowym takim jak poniżej.
Należy pamiętać, że ten kod jest tylko uproszczonym przykładem. Zastosowanie produkcyjne wymagałoby oczyszczenia go na różne sposoby (bezpieczeństwo wątków, sprawdzanie błędów, sprawdzanie rozmiaru bufora itp.).
Jest używany jak w poniższym kodzie. Kompiluje się czysto i działa poprawnie w moich testach na gcc, vc2003 i vc2008:
Anonimowy użytkownik
Potwierdzenie od:
Miałem dokładnie ten sam problem i właśnie natrafiłem na rozwiązanie, które nie wymaga konwersji oryginalnych ciągów na szerokie znaki iz powrotem: zapisz oryginalny plik jako UTF-8
bez
podpis, a VC2008 pozostawi go w spokoju. Zadziałało świetnie, kiedy wymyśliłem rezygnację z podpisu. Podsumować:
Unicode (UTF-8 unsigned) to strona kodowa 65001, nie generuje ostrzeżenia c4566 w VC2008 i nie powoduje bałaganu VC z kodowaniem, podczas gdy strona kodowa 65001 (podpisana UTF-8) rzuca c4566 (jak już odkryłeś) .
Mam nadzieję, że nie jest za późno, aby Ci pomóc, ale może to przyspieszyć działanie Twojej aplikacji VC2008 i usunąć obejście.
Anonimowy użytkownik
Potwierdzenie od:
Wierzę, że to zadziała dobrze, tylko niezbyt czytelne, więc jeśli tak, skomentuj, aby wyjaśnić.
Anonimowy użytkownik
Potwierdzenie od:
Plik/Rozszerzony
Opcje zachowania/kodowanie: „Unicode (UTF-8 bez podpisu) - strona kodowa 65001”
Anonimowy użytkownik
Potwierdzenie od:
[/*]
[*]
UTF-8 bez BOM:
[/*]
[*]
UTF-8 z BOM:
[/*]
[/list]
Widzisz, kompilator C obsługuje pliki UTF-8 bez BOM w taki sam sposób jak CP1252. W rezultacie kompilator nie może mieszać łańcuchów UTF-8 i UTF-16 w skompilowanym wyjściu! Musisz więc zdecydować się na jeden plik źródłowy:
Niezależnie od tego, EDITOR może automatycznie wykrywać pliki UTF-8 bez BOM jako pliki UTF-8.
Anonimowy użytkownik
Potwierdzenie od:
„Używanie UTF-8 jako wewnętrznej reprezentacji ciągu w C i C ++ w programie Visual Studio”
=>
http://www.nubaria.com/ru/blog/?p=289
http://www.nubaria.com/en/blog/?p=289
Wymaga to Visual Studio 2008 SP1 i poniżej poprawki:
http://support.microsoft.com/kb/980263
http://support.microsoft.com/kb/980263
....
Anonimowy użytkownik
Potwierdzenie od:
zamienione na
Oczywiście jest to nieczytelne dla każdego, a celem jest tylko uniknięcie problemów z kompilatorem.
Możesz użyć preprocesora C ++, aby odwołać się do ciągów w przekonwertowanym pliku nagłówkowym lub przekonwertować cały kod źródłowy UTF-8 na ASCII przed kompilacją przy użyciu tej sztuczki.
Anonimowy użytkownik
Potwierdzenie od:
Teoretycznie powrót z UTF-16 do UTF-8 powinien być równie łatwy, ale stwierdziłem, że ustawienia regionalne UTF-8 nie działają zgodnie z oczekiwaniami w moim systemie (VC10 Express na Win7).
Dlatego napisałem prosty konwerter oparty na RFC 3629.
Uważam, że to powinno działać na każdej platformie, ale nie byłem w stanie przetestować tego poza własnym systemem, więc może zawierać błędy.
Anonimowy użytkownik
Potwierdzenie od:
lub:
Anonimowy użytkownik
Potwierdzenie od:
ć
miał tylko jeden bajt.
Rozwiązaniem dla mnie było zapisanie w UTF-8 i brak BOM. W ten sposób oszukałem kompilator. Teraz myśli, że to zwykłe źródło i nie tłumaczy wierszy. W plikach .obj
teraz są dwa bajty.
Proszę zignorować niektórych komentatorów. Rozumiem, czego chcesz - chcę tego samego: pliki źródłowe UTF-8, pliki wygenerowane w formacie UTF-8, pliki wejściowe UTF-8, UTF-8 przez łącza bez żadnego tłumaczenia.
Może to pomoże ...
Anonimowy użytkownik
Potwierdzenie od:
opowiedz o tym
https://raymai97.github.io/myb ... ml... W przypadku programu Visual C ++ 2005 i nowszych, jeśli plik źródłowy nie zawiera BOM (Byte Order Sign), a system ustawień regionalnych nie jest angielski, VC założy, że plik źródłowy nie jest w formacie Unicode.
Aby Twoje pliki źródłowe UTF-8 poprawnie się kompilowały, musisz
zapisz je na UTF-8 bez
Kodowania BOM i
System lokalizacji (język inny niż Unicode) musi być angielski
.
https://i.stack.imgur.com/8W0wd.png
Anonimowy użytkownik
Potwierdzenie od:
Teraz mam rozwiązanie.
Przede wszystkim musisz pracować pod lokalną jednobajtową stroną kodową, taką jak angielska, aby cl.exe nie otrzymywał kodów wprowadzających chaos.
Po drugie, zachowaj kod źródłowy utf8-encoded-no BOM, pamiętaj o no-boom, a następnie skompiluj z
cl.exe, DO nie wywołuje żadnego C API, takiego jak printf wprint, wszyscy ci pracownicy nie działają, nie wiem dlaczego :) .... może zrobię trochę badań później ...
Następnie po prostu skompiluj i uruchom, zobaczysz wynik .....
mój e-mail to loyangan, (google) mam nadzieję, że ......
Obiekt WScript:
Wykonanie skryptu run.bat
Pobieranie pakietu źródłowego main.c:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Jedynym przenośnym i niezależnym od kompilatora sposobem jest użycie kodowania ASCII i sekwencji ucieczki, ponieważ nie ma gwarancji, że jakikolwiek kompilator zaakceptuje plik zakodowany w formacie UTF-8.
Anonimowy użytkownik
Potwierdzenie od:
Szczegółowo udokumentowałem pod adresem
https://github.com/jay/compiler_string_test
https://github.com/jay/compiler_string_test
[1]: Visual Studio 2012 nie obsługuje Execution_character_set. Visual Studio 2010 i 2015 działa dobrze i jak wiesz z poprawką 2008 działa dobrze.
[2]: Kilka komentarzy w tym wątku wskazuje, że użycie ani BOM, ani pragmy może prowadzić do nieprawidłowej konwersji dla programistów korzystających z lokalnej strony kodowej, która jest wielobajtowa (np. Japonia).
Anonimowy użytkownik
Potwierdzenie od:
absolutne minimum, które każdy programista absolutnie musi wiedzieć o Unicode i zestawach znaków (bez wymówek!)
http://www.joelonsoftware.com/ ... .html
na
Joel On Software
http://www.joelonsoftware.com
...
Anonimowy użytkownik
Potwierdzenie od: