Porównaj ceny domen i usług IT, sprzedawców z całego świata

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.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Aktualizacja:
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):
  • literały łańcuchowe są używane bez zmian (nieprzetworzone ciągi)
  • obsługuje pliki źródłowe zakodowane w UTF-8
  • pliki źródłowe nie mogą mieć BOM UTF-8

vc2003:
  • literały łańcuchowe są używane bez zmian (nieprzetworzone ciągi)
  • obsługuje pliki źródłowe zakodowane w UTF-8
  • pliki źródłowe mogą, ale nie muszą, mieć BOM UTF-8 (to nie ma znaczenia)

vc2005+:
  • Literały ciągów są masowane przez kompilator (bez nieprzetworzonych ciągów)
  • Literały łańcuchów znaków są przekodowywane na określone ustawienia regionalne
  • UTF-8 nie jest obsługiwany jako docelowy język
  • pliki źródłowe muszą mieć BOM UTF-8

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.
#if defined(_MSC_VER) && _MSC_VER > 1310
// Visual C++ 2005 and later require the source files in UTF-8, and all strings
// to be encoded as wchar_t otherwise the strings will be converted into the
// local multibyte encoding and cause errors. To use a wchar_t as UTF-8, these
// strings then need to be convert back to UTF-8. This function is just a rough
// example of how to do this.
# define utf8(str) ConvertToUTF8(L##str)
const char * ConvertToUTF8(const wchar_t * pStr) {
static char szBuf[1024];
WideCharToMultiByte(CP_UTF8, 0, pStr, -1, szBuf, sizeof(szBuf), NULL, NULL);
return szBuf;
}
#else
// Visual C++ 2003 and gcc will use the string literals as is, so the files
// should be saved as UTF-8. gcc requires the files to not have a UTF-8 BOM.
# define utf8(str) str
#endif

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:
std::string mText;
mText = utf8("Chinese (Traditional)");
mText = utf8("中国語 (繁体)");
mText = utf8("중국어 (번체)");
mText = utf8("Chinês (Tradicional)");
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Broofield,
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

Anonimowy użytkownik

Potwierdzenie od:

Chociaż prawdopodobnie najlepiej jest użyć szerokich ciągów, a następnie przekonwertować je w razie potrzeby na UTF-8. Myślę, że najlepszym rozwiązaniem, jak wspomniałeś, jest użycie znaków szesnastkowych na łańcuchach. Na przykład, załóżmy, że potrzebujesz punktu kodowego
\ uC911
, możesz to po prostu zrobić.
const char *str = "\xEC\xA4\x91";

Wierzę, że to zadziała dobrze, tylko niezbyt czytelne, więc jeśli tak, skomentuj, aby wyjaśnić.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Plik/Rozszerzony

Opcje zachowania/kodowanie: „Unicode (UTF-8 bez podpisu) - strona kodowa 65001”
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Standardowe zachowanie kompilatora Visual C ++ (2005+) dla plików źródłowych:
  • CP1252 (na przykład zachodnioeuropejska strona kodowa): [list][*]
    "Ä"
    C4 00
  • 'Ä'
    C4
  • L"Ä"
    00C4 0000
  • L'Ä'
    00C4

[/*]
[*]
UTF-8 bez BOM:
  • "Ä"
    C3 84 00
    (= UTF-8)
  • „Ę”
    -> ostrzeżenie: stała wielowartościowa
  • „Ω”
    E2 84 A6 00
    (= UTF-8 zgodnie z oczekiwaniami)
  • L "A"
    00C3 0084 0000
    (źle!)
  • L'Ę '
    -> ostrzeżenie: stała wielowartościowa
  • L "Ω"
    00E2 0084 00A6 0000
    (źle!)

[/*]
[*]
UTF-8 z BOM:
  • „Ę”
    C4 00
    (= CP1252, koniec UTF-8),
  • 'Ä'
    C4
  • „Ω”
    → błąd: nie można przekonwertować na CP1252!
  • L "Ą
    00C4 0000
    (poprawnie)
  • L'Ä'
    00C4
  • L "Ω"
    2126 0000
    (poprawnie)

[/*]
[/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:
  • lub używaj UTF-8 z BOM i generuj tylko łańcuchy UTF-16 (tj. zawsze używaj prefiksu
    L
    ),
  • lub UTF-8 bez BOM i generuj tylko ciągi znaków UTF-8 (tj. Nigdy nie używaj prefiksu
    L
    ).
  • 7-bitowe znaki ASCII nie są używane i można ich używać z prefiksem
    L
    lub bez niego

Niezależnie od tego, EDITOR może automatycznie wykrywać pliki UTF-8 bez BOM jako pliki UTF-8.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Z komentarza na tym bardzo fajnym blogu

„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
#pragma execution_character_set("utf-8")
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

Anonimowy użytkownik

Potwierdzenie od:

Co powiesz na to? Przechowujesz ciągi w pliku zakodowanym w formacie UTF-8, a następnie wstępnie przetwarzasz je w pliku źródłowym zakodowanym w ASCII C ++. Zachowujesz kodowanie UTF-8 wewnątrz łańcucha za pomocą znaków szesnastkowych. Strunowy
"中国語 (繁体)"

zamienione na
"\xE4\xB8\xAD\xE5\x9B\xBD\xE8\xAA\x9E (\xE7\xB9\x81\xE4\xBD\x93)"

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

Anonimowy użytkownik

Potwierdzenie od:

Przenośna konwersja z dowolnego natywnego kodowania, jakie posiadasz, po prostu za pomocą funkcji char_traits :: widen ().
#include <locale>
#include <string>
#include <vector>/////////////////////////////////////////////////////////
// NativeToUtf16 - Convert a string from the native
// encoding to Unicode UTF-16
// Parameters:
// sNative (in): Input String
// Returns: Converted string
/////////////////////////////////////////////////////////
std::wstring NativeToUtf16(const std::string &sNative)
{
std::locale locNative;// The UTF-16 will never be longer than the input string
std::vector<wchar_t> vUtf16(1+sNative.length());// convert
std::use_facet< std::ctype<wchar_t> >(locNative).widen( sNative.c_str(),
sNative.c_str()+sNative.length(),
&vUtf16[0]); return std::wstring(vUtf16.begin(), vUtf16.end());
}

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.
/////////////////////////////////////////////////////////
// Utf16ToUtf8 - Convert a character from UTF-16
// encoding to UTF-8.
// NB: Does not handle Surrogate pairs.
// Does not test for badly formed
// UTF-16
// Parameters:
// chUtf16 (in): Input char
// Returns: UTF-8 version as a string
/////////////////////////////////////////////////////////
std::string Utf16ToUtf8(wchar_t chUtf16)
{
// From RFC 3629
// 0000 0000-0000 007F 0xxxxxxx
// 0000 0080-0000 07FF 110xxxxx 10xxxxxx
// 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx// max output length is 3 bytes (plus one for Nul)
unsigned char szUtf8[4] = ""; if (chUtf16 < 0x80)
{
szUtf8[0] = static_cast<unsigned char>(chUtf16);
}
else if (chUtf16 < 0x7FF)
{
szUtf8[0] = static_cast<unsigned char>(0xC0 | ((chUtf16>>6)&0x1F));
szUtf8[1] = static_cast<unsigned char>(0x80 | (chUtf16&0x3F));
}
else
{
szUtf8[0] = static_cast<unsigned char>(0xE0 | ((chUtf16>>12)&0xF));
szUtf8[1] = static_cast<unsigned char>(0x80 | ((chUtf16>>6)&0x3F));
szUtf8[2] = static_cast<unsigned char>(0x80 | (chUtf16&0x3F));
} return reinterpret_cast<char *>(szUtf8);
}
/////////////////////////////////////////////////////////
// Utf16ToUtf8 - Convert a string from UTF-16 encoding
// to UTF-8
// Parameters:
// sNative (in): Input String
// Returns: Converted string
/////////////////////////////////////////////////////////
std::string Utf16ToUtf8(const std::wstring &sUtf16)
{
std::string sUtf8;
std::wstring::const_iterator itr; for (itr=sUtf16.begin(); itr!=sUtf16.end(); ++itr)
sUtf8 += Utf16ToUtf8(*itr);
return sUtf8;
}

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.
#include <iostream>
#include <fstream>int main()
{
const char szTest[] = "Das tausendschöne Jungfräulein,\n"
"Das tausendschöne Herzelein,\n"
"Wollte Gott, wollte Gott,\n"
"ich wär' heute bei ihr!\n"; std::wstring sUtf16 = NativeToUtf16(szTest);
std::string sUtf8 = Utf16ToUtf8(sUtf16); std::ofstream ofs("test.txt");
if (ofs)
ofs << sUtf8;
return 0;
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Może spróbuj eksperymentu:
#pragma setlocale(".UTF-8")

lub:
#pragma setlocale("english_england.UTF-8")
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Miałem podobny problem. Moje literały łańcuchowe UTF-8 zostały przekonwertowane na bieżącą stronę kodową systemu w czasie kompilacji - właśnie otworzyłem pliki .obj w przeglądarce szesnastkowej i były one już zniekształcone. Na przykład symbol

ć

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

Anonimowy użytkownik

Potwierdzenie od:

Wiem, że spóźniłem się na imprezę, ale myślę, że potrzebuję

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

Anonimowy użytkownik

Potwierdzenie od:

To znaczy, że trzeba coś zmienić.
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:
#!/usr/bin/env python
# encoding: utf-8
# Yonggang Luo# the following two variables are used by the target "waf dist"
VERSION='0.0.1'
APPNAME='cc_test'top = '.'import waflib.Configuredef options(opt):
opt.load('compiler_c')def configure(conf):
conf.load('compiler_c')
conf.check_lib_msvc('gdi32')
conf.check_libs_msvc('kernel32 user32')def build(bld):
bld.program( features = 'c',
source = 'chinese-utf8-no-bom.c',
includes = '. ..',
cflags = ['/wd4819'],
target = 'myprogram',
use = 'KERNEL32 USER32 GDI32')

Wykonanie skryptu run.bat
rd/s/q build
waf configure build --msvc_version "msvc 6.0"
build\myprogramrd/s/q build
waf configure build --msvc_version "msvc 9.0"
build\myprogramrd/s/q build
waf configure build --msvc_version "msvc 10.0"
build\myprogram

Pobieranie pakietu źródłowego main.c:
//encoding : utf8 no-bom
#include <stdio.h>
#include <string.h>#include <Windows.h>char* ConvertFromUtf16ToUtf8(const wchar_t *wstr)
{
int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
if(requiredSize > 0)
{
char *buffer = malloc(requiredSize + 1);
buffer[requiredSize] = 0;
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, buffer, requiredSize, 0, 0);
return buffer;
}
return NULL;
}wchar_t* ConvertFromUtf8ToUtf16(const char *cstr)
{
int requiredSize = MultiByteToWideChar(CP_UTF8, 0, cstr, -1, 0, 0);
if(requiredSize > 0)
{
wchar_t *buffer = malloc( (requiredSize + 1) * sizeof(wchar_t) );
printf("converted size is %d 0x%x\n", requiredSize, buffer);
buffer[requiredSize] = 0;
MultiByteToWideChar(CP_UTF8, 0, cstr, -1, buffer, requiredSize);
printf("Finished\n");
return buffer;
}
printf("Convert failed\n");
return NULL;
}void ShowUtf8LiteralString(char const *name, char const *str)
{
int i = 0;
wchar_t *name_w = ConvertFromUtf8ToUtf16(name);
wchar_t *str_w = ConvertFromUtf8ToUtf16(str); printf("UTF8 sequence\n");
for (i = 0; i < strlen(str); ++i)
{
printf("x ", (unsigned char)str[i]);
} printf("\nUTF16 sequence\n");
for (i = 0; i < wcslen(str_w); ++i)
{
printf("x ", str_w[i]);
}//Why not using printf or wprintf? Just because they do not working:)
MessageBoxW(NULL, str_w, name_w, MB_OK);
free(name_w);
free(str_w);}int main()
{
ShowUtf8LiteralString("English english_c", "Chinese (Traditional)");
ShowUtf8LiteralString("简体 s_chinese_c", "你好世界");
ShowUtf8LiteralString("繁体 t_chinese_c", "中国語 (繁体)");
ShowUtf8LiteralString("Korea korea_c", "중국어 (번체)");
ShowUtf8LiteralString("What? what_c", "Chinês (Tradicional)");
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Miałem podobny problem, rozwiązaniem było zapisywanie do UTF8 bez korzystania z zaawansowanych opcji zapisu
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Pliki źródłowe UTF-8
  • Bez BOM : są traktowane jako nieprzetworzone, z wyjątkiem sytuacji, gdy system używa strony kodowej o rozmiarze & > 1 bajt/znak (jak Shift JIS). Musisz zmienić stronę kodową systemu na dowolny pojedynczy bajt, a następnie możesz używać znaków Unicode wewnątrz literałów i kompilować bez problemów (przynajmniej mam taką nadzieję).
  • Z BOM : czy były to literały znaków i ciągów znaków przekonwertowane na stronę kodową systemu w czasie kompilacji. Możesz sprawdzić aktualną stronę kodową systemu za pomocą GetACP (). AFAIK, nie ma możliwości ustawienia strony kodowej systemu na 65001 (UTF-8), więc nie ma możliwości użycia UTF-8 bezpośrednio z BOM.

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

Anonimowy użytkownik

Potwierdzenie od:

Miałem podobny problem z kompilacją literałów ciągów wąskich (znaków) UTF-8 i stwierdziłem, że w zasadzie potrzebuję zarówno BOM UTF-8, jak i
#pragma Execution_character_set ("utf-8")
[1] lub ani BOM, ani pragma [2]. Użycie jednego bez drugiego spowodowało niepoprawną konwersję.
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

Anonimowy użytkownik

Potwierdzenie od:

Zgadzam się z Theo, niecierpliwie czekając na wiadomości. Przeczytaj artykuł

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

Anonimowy użytkownik

Potwierdzenie od:

Przeczytaj artykuły. Po pierwsze, nie chcesz UTF-8. UTF-8 to tylko sposób reprezentowania znaków. Potrzebujesz szerokich znaków (wchar_t). Piszesz je jako L "yourtextgoeshere". Typ tego literału to wchar_t *. jeśli się spieszysz, spójrz na wprintf.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się