Как создать строковый литерал UTF-8 в Visual C++ 2008

В VC ++ 2003, я мог просто сохранить исходный файл как UTF-8, и все строки были использованы как есть. Другими словами, следующий код распечатал бы строки, как к консоли. Если бы исходный файл был сохранен как UTF-8 затем, то вывод был бы UTF-8.

printf("Chinese (Traditional)");
printf("中国語 (繁体)");
printf("중국어 (번체)");
printf("Chinês (Tradicional)");

Я сохранил файл в формате UTF-8 с BOM UTF-8. Однако компиляция с VC2008 приводит к:

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.

Символы, вызывающие эти предупреждения, повреждаются. Те, которые действительно соответствуют локали (в этом случае 932 = японский язык) преобразовываются в кодирование локали, т.е. Shift JIS.

Я не могу найти способ заставить VC ++ 2008 компилировать это для меня. Обратите внимание, что не имеет значения, какую локаль я использую в исходном файле. Кажется, нет локали, которая говорит, что "Я знаю то, что я делаю, не делайте % f$ ##ng изменяет мои строковые литералы". В частности, бесполезная псевдолокаль UTF-8 не работает.

#pragma setlocale(".65001") 
=> error C2175: '.65001' : invalid locale

Ни один не делает "C":

#pragma setlocale("C") 
=> see warnings above (in particular locale is still 932)

Кажется, что VC2008 вызывает все символы в указанное (или значение по умолчанию) локаль, и что локаль не может быть UTF-8. Я не хочу изменять файл для использования строк Escape как "\xbf\x11...", потому что тот же источник компилируется с помощью gcc, который может вполне счастливо иметь дело с файлами UTF-8.

Там какой-либо путь состоит в том, чтобы указать, что компиляция исходного файла должна оставить строковые литералы нетронутыми?

Для выяснения у этого по-другому какие флаги компиляции могут, я использую для определения обратной совместимости с VC2003 при компиляции исходного файла. т.е. не изменяйте строковые литералы, используйте их байт для байта как они.

Обновление

Спасибо за предложения, но я хочу избежать wchar. Начиная с этого приложения соглашения со строками в UTF-8 исключительно, с помощью wchar затем потребовали бы, чтобы я преобразовал все строки назад в UTF-8, который должен быть ненужным. Весь вход, вывод и внутренняя обработка находятся в UTF-8. Это - простое приложение, которое хорошо работает, как находится на Linux и при компиляции с VC2003. Я хочу смочь скомпилировать то же приложение с VC2008 и иметь его работа.

Чтобы это произошло, мне нужен VC2008, чтобы не попытаться преобразовать его в локаль моей локальной машины (японский язык, 932). Я хочу, чтобы VC2008 был обратно совместим с VC2003. Я хочу локаль или параметр компилятора, который говорит, что строки использованы как есть, по существу как непрозрачные массивы символа, или как UTF-8. Похоже, что я мог бы застрять с VC2003 и gcc, хотя, VC2008 пытается быть слишком умным в этом экземпляре.

1
задан 29 March 2009 в 07:29

18 ответов

Обновление:

Я решил, что нет никакого гарантируемого способа сделать это. Решение, которое я представляю ниже работ для английской версии VC2003, но сбои при компиляции с японской версией VC2003 (или возможно это - японская ОС). В любом случае это не может зависеться от работать. Обратите внимание, что, даже объявляя все как L"" строки не работало (и является болезненным в gcc, как описано ниже).

Вместо этого я полагаю, что просто необходимо стиснуть зубы и переместить весь текст в файл данных и загрузить его оттуда. Я теперь храню и получаю доступ к тексту в файлах INI через SimpleIni (межплатформенная библиотека INI-файла). По крайней мере, существует гарантия, что это работает, как весь текст вне программы.

Исходный:

Я отвечаю на это сам с тех пор, только Evan, казалось, понял проблему. Ответы относительно того, что Unicode и как использовать wchar_t, не важны для этой проблемы, поскольку это не об интернационализации, ни неверном толковании Unicode, кодировок символов. Я ценю Вашу попытку помочь, хотя, извинения, если я не был достаточно ясен.

Проблема состоит в том, что у меня есть исходные файлы, которые должны быть кросс-скомпилированы под множеством платформ и компиляторов. Программа делает обработку UTF-8. Это не заботится ни о какой другой кодировке. Я хочу иметь строковые литералы в UTF-8 как в настоящее время работы с gcc и vc2003. Как я делаю это с VC2008? (т.е. обратно совместимое решение).

Это - то, что я нашел:

gcc (v4.3.2 20081105):

  • строковые литералы использованы как есть (необработанные строки)
  • поддержки UTF-8 закодировали исходные файлы
  • исходные файлы не должны иметь BOM UTF-8

vc2003:

  • строковые литералы использованы как есть (необработанные строки)
  • поддержки UTF-8 закодировали исходные файлы
  • исходные файлы могут или не могут иметь BOM UTF-8 (он не имеет значения),

vc2005 +:

  • строковые литералы массажируются компилятором (никакие необработанные строки)
  • символьные строковые литералы повторно кодируются к указанной локали
  • UTF-8 не поддерживается как целевая локаль
  • исходные файлы должны иметь BOM UTF-8

Так, простой ответ - то, что для этой конкретной цели, VC2005 + повреждается и не предоставляет обратно совместимый путь компиляции. Единственный способ получить строки Unicode в скомпилированную программу через UTF-8 + BOM + wchar, что означает, что я должен преобразовать все строки назад в UTF-8 во время использования.

Нет никакого простого межплатформенного метода преобразования wchar к UTF-8, например, в чем размер и кодирование являются wchar? В Windows, UTF-16. На других платформах? Это варьируется. См. проект ICU для некоторых деталей.

В конце я решил, что избегу стоимости преобразования на всех компиляторах кроме vc2005 + с источником как следующее.

#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

Обратите внимание, что этот код является просто упрощенным примером. Производственное использование должно было бы очистить его во множестве путей (потокобезопасность, проверка ошибок, проверки размера буфера, и т.д.).

Это используется как следующий код. Это компилирует чисто и работает правильно в моих тестах на gcc, vc2003, и vc2008:

std::string mText;
mText = utf8("Chinese (Traditional)");
mText = utf8("中国語 (繁体)");
mText = utf8("중국어 (번체)");
mText = utf8("Chinês (Tradicional)");
33
ответ дан 31 October 2019 в 06:07

Эти два шестнадцатеричных числа в

Not a JPEG file: starts with 0x48 0x54

переведите в ASCII HT то, которое я предполагаю, продолжает HTTP[...]. Проверьте заголовок файла с xxd -l 20 img.jpg. Это должно ожидаться вывод от последней команды, которую Вы отправили с тех пор

wget --save-headers

сообщает wget предварительно ожидать вывод с HTTP заголовок ответа.

Два других вызова не сделают этого.


Я просто протестировал Ваш сценарий, и он работает с также curl или wget. Для wget загружать файл, пользовательскую строку -U необходим, иначе сервер отказывается. Любое использование
curl -o img.jpg $1

или

wget -U "Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.17  (KHTML,   Gecko) Ubuntu/11.04 Chromium/11.0.654.0 Chrome/11.0.654.0  Safari/534.17" $1 -O img.jpg

без --save-headers.

1
ответ дан 28 July 2019 в 20:46
  • 1
    Мне действительно нравится это, это вроде того, для чего я схватывал с моим желанием использовать, находят. Существует ли способ только создать прописные имена каталогов и переместить имена файлов нижнего регистра в них? – Arronical 11 January 2017 в 06:52

Прочитайте статьи. Во-первых, Вы не хотите UTF-8. UTF-8 является только способом представить символы. Вы хотите широкие символы (wchar_t). Вы записываете их как L "yourtextgoeshere". Тип того литерала является wchar_t*. Если Вы спешите, просто ищете wprintf.

-6
ответ дан 31 October 2019 в 06:07

Необходимо Загрузить Драйвер с веб-сайта Брата

, Чтобы проверить, выполняете ли Вы рабочие 32 бита или 64 бита этот Результат команды

uname -a

для 32-разрядной Ubuntu:

Linux discworld 2.6.38-8-универсальный # SMP с 42 Ubuntu понедельник 11 апреля 3:31:50 UTC 2011 GNU/Linux i686 i686 i386

, тогда как 64-разрядная Ubuntu покажет:

Linux discworld 2.6.38-8-универсальный # SMP с 42 Ubuntu понедельник 11 апреля 3:31:50 UTC 2011 GNU/Linux x86_64 x86_64 x86_64 , если Вы выполняете версию на 32 бита Ubuntu.

выполняет эти команды, если Вы находитесь на 32 битах

wget http://download.brother.com/welcome/dlf100975/libsane-dsseries_1.0.5-1_i386.deb 

sudo dpkg -i --force-all  libsane-dsseries_1.0.5-1_i386.deb

при выполнении выполнения на 64 бита эти команды.

wget http://download.brother.com/welcome/dlf100976/libsane-dsseries_1.0.5-1_amd64.deb

sudo dpkg -i --force-all  libsane-dsseries_1.0.5-1_amd64.deb

Драйвер сканера Брата, Как Установить

-3
ответ дан 31 October 2019 в 16:07
  • 1
    Да, у меня есть статический адрес ipv4, ipv6. Я спрошу информацию в поставщике, которого является недостаточно для ответа. Спасибо за ссылку на учебное руководство. Это была проблема, я искал ее Ubuntu, но было необходимо искать Debian. – Sylon 26 January 2017 в 05:22

Я не уверен, что Вы спрашиваете, но Вы могли сделать что-то вроде этого:

Скажем, Вы находитесь в каталоге, в котором у Вас есть папки folder1 и файлы A, B и A123, A456, A789.

можно переместить файл с помощью команды:

mv A folder1

Это перемещает файл A в folder1

mv A* folder1

, Это перемещает файлы A123, A456 и A789 в folder1.

, Если Вы хотите переместить те файлы в подпапку folder1, скажем, subfolder1, просто сделайте:

mv A* folder1/subfolder1
16
ответ дан 31 October 2019 в 16:07
  • 1
    Можно получить низкую мощность GPU это won' t требуют обновления Вашего PSU. – Android Dev 24 January 2017 в 07:11

Можно запустить скрипт с bash -x для наблюдения точно, что он делает. Я заметил, что это сравнивало "expr 2 - 1", чтобы видеть, было ли это равно 0, который выглядел неправильным. Я думаю, что эта строка является неправильной:

c='expr $c - 1"

кавычки не соответствуют, таким образом, я первоначально предложил использовать двойные кавычки, но что Вы хотите, должен присвоиться результат из выполнения expr и тому подобное к c переменная, таким образом, Вам нужны обратные галочки:

c=`expr $c - 1`

при фиксации этого и верхнего регистра If близость начало сценарий, кажется, работает правильно.

0
ответ дан 31 October 2019 в 16:07
  • 1
    Вы не можете изменить параметр конфигурации ядра через личинку. Так как я don' t знают, какова Ваша цель, я не могу прокомментировать далее. Вы могли рассмотреть Documentation/admin-guide/kernel-parameters.txt (старое местоположение Documentation/kernel-parameters.txt), сами, но я didn' t видят что-либо очевидное там. – Doug Smythies 22 January 2017 в 07:14

У меня была подобная проблема при компиляции UTF-8 узкие (символьные) строковые литералы и что я обнаружил, в основном, у меня должен был быть и BOM UTF-8 и #pragma execution_character_set("utf-8") [1], или ни BOM, ни прагма [2]. Используя одного без другого привел к неправильному преобразованию.

я зарегистрировал детали в https://github.com/jay/compiler_string_test

[1]: Visual Studio 2012 не поддерживает execution_character_set. 2010 и 2015 Visual Studio это хорошо работает, и поскольку Вы знаете с патчем в 2008, что это хорошо работает.

[2]: Некоторые комментарии в этом потоке отметили, что использование ни BOM, ни прагма может привести к неправильному преобразованию для разработчиков, использующих локальную кодовую страницу, которая является многобайтовой (например, Япония).

0
ответ дан 31 October 2019 в 16:07

Исходные файлы UTF-8

  • Без BOM: рассматриваются как сырые данные кроме того, если Ваша система использует> 1byte/char кодовая страница (как Shift JIS). Необходимо изменить системную кодовую страницу на любой единственный байт один, и затем необходимо смочь использовать символы Unicode в литералах и компиляции без проблем (по крайней мере, я надеюсь).
  • С BOM: они имеют, обугливаются и строковые литералы, преобразованные в системную кодовую страницу во время компиляции. Можно проверить кодовую страницу существующей системы с GetACP (). AFAIK, нет никакого способа установить системную кодовую страницу на 65 001 (UTF-8), поэтому следовательно, нет никакого способа использовать UTF-8 непосредственно с BOM.

единственное портативное устройство и компилятор независимый путь состоит в том, чтобы использовать набор символов ASCII и escape-последовательности, потому что нет никаких гарантий, что любой компилятор признал бы, что UTF-8 закодировал файл.

0
ответ дан 31 October 2019 в 16:07

Так, вещи, которые будут изменены. Теперь я получил решение.

, В первую очередь, Вы должны, работая в соответствии с Единственной Локальной Кодовой страницей Байта, такой как английский язык, так, чтобы cl.exe не был, получая коды добраться, чтобы быть хаосом.

115-секундный, сохраните исходный код в UTF8-НИКАКОМ BOM, заметьте, без BOM, и затем скомпилируйте с cl.exe, СДЕЛАЙТЕ не вызов любого API C, такой как, printf wprint, все те сотрудники, не работающие, я не знаю почему:).... может иметь исследование позже...

Затем просто компиляция и выполнение, Вы будете видеть результат..... моя электронная почта является luoyonggang, надеждой (Google) на некоторых......

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.Configure

def 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')

Под управлением сценарий исходный код run.bat

rd /s /q build
waf configure build --msvc_version "msvc 6.0"
build\myprogram

rd /s /q build
waf configure build --msvc_version "msvc 9.0"
build\myprogram

rd /s /q build
waf configure build --msvc_version "msvc 10.0"
build\myprogram

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("%02x ", (unsigned char)str[i]);
    }

    printf("\nUTF16 sequence\n");
    for (i = 0; i < wcslen(str_w); ++i)
    {
        printf("%04x ", 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)");
}
0
ответ дан 31 October 2019 в 16:07

Я знаю, что опаздываю в сторону, но я думаю, что я должен к распространить это . Для Visual C++ 2005 и выше, если исходный файл doesn’t содержит BOM (метка порядка байтов), и Ваша системная локаль не является английской, VC предположит, что Ваш исходный файл не находится в Unicode.

, Чтобы скомпилировать Ваши исходные файлы UTF-8 правильно, Вы должны сохранять в UTF-8 без кодирования BOM, и , системная локаль (язык не-Unicode) должна быть английская .

enter image description here

1
ответ дан 31 October 2019 в 16:07

У меня была подобная проблема. Мои строковые литералы UTF-8 были преобразованы в кодовую страницу существующей системы во время компиляции - я просто открыл .obj файлы в шестнадцатеричном средстве просмотра, и они были уже искажены. Например, символ Д ‡ был всего один байт.

решение для меня состояло в том, чтобы сохранить в UTF-8 и БЕЗ BOM. Это - то, как я обманул компилятор. Это теперь думает, что это - просто нормальный источник и не переводит строки. В .obj файлах Д ‡ - теперь два байта.

Игнорирование некоторые комментаторы. Я понимаю то, что Вы хотите - я хочу то же также: источник UTF-8, UTF-8 генерировал файлы, входные файлы UTF-8, UTF-8 по линиям связи без когда-либо перевода.

, Возможно, это помогает...

1
ответ дан 31 October 2019 в 16:07

Возможно, попробуйте эксперимент:

#pragma setlocale(".UTF-8")

или:

#pragma setlocale("english_england.UTF-8")
1
ответ дан 31 October 2019 в 16:07

Портативное преобразование от любого собственного компонента, кодирующего Вас, имеет, простое использование char_traits:: расширитесь ().

#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());
}

В теории, поездка обратно, от UTF-16 до UTF-8 должна быть столь же легкой, но я нашел, что локали UTF-8 не работают правильно над моей системой (Экспресс VC10 на Win7).

Таким образом я записал простой преобразователь на основе 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;
}

, я полагаю, что это должно работать над любой платформой, но я не смог протестировать его за исключением своей собственной системы, таким образом, это может иметь ошибки.

#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;
}
3
ответ дан 31 October 2019 в 16:07

От комментария до этого очень хорошего блога
"Используя UTF-8 как внутреннее представление для строк в C и C++ с Visual Studio"
=> http://www.nubaria.com/en/blog/?p=289

#pragma execution_character_set("utf-8") 

Это требует Visual Studio 2008 SP1 и следующих текущих исправлений:

http://support.microsoft.com/kb/980263 ....

6
ответ дан 31 October 2019 в 16:07

Visual C++ (2005 +) поведение стандарта КОМПИЛЯТОРА для исходных файлов:

  • CP1252 (для этого примера, западноевропейской кодовой страницы):
    • "Ä" в †’ C4 00
    • 'Ä' в †’ C4
    • L"Ä" в †’ 00C4 0000
    • L'Ä' в †’ 00C4
  • UTF-8 без BOM:
    • "Ä" в †’ C3 84 00 (= UTF-8)
    • 'Ä' в †’ предупреждение: мультисимвольная константа
    • "Ω" в †’ E2 84 A6 00 (= UTF-8, как ожидалось)
    • L"A" в †’ 00C3 0084 0000 (неправильно!)
    • L'Ä' в †’ предупреждение: мультисимвольная константа
    • L"Ω" в †’ 00E2 0084 00A6 0000 (неправильно!)
  • UTF-8 с BOM:
    • "Ä" в †’ C4 00 (= CP1252, больше никакого UTF-8),
    • 'Ä' в †’ C4
    • "Ω" в †’ ошибка: не может преобразовать в CP1252!
    • L"Ä" в †’ 00C4 0000 (корректный)
    • L'Ä' в †’ 00C4
    • L"Ω" в †’ 2126 0000 (корректный)

Вы видите, компилятор C обрабатывает файлы UTF-8 без BOM тот же путь как CP1252. В результате для компилятора невозможно смешать UTF-8 и строки UTF-16 в скомпилированный вывод! Таким образом, необходимо решить для одного файла исходного кода:

  • любой использование UTF-8 с BOM и генерируют строки UTF-16 только (т.е. всегда используйте L префикс),
  • или UTF-8 без BOM и генерируют строки UTF-8 только (т.е. никогда не используйте L префикс).
  • 7-разрядные символы ASCII не включены и могут использоваться с или без [1 131] префикс

Независимо, РЕДАКТОР может автоматически обнаружить файлы UTF-8 без BOM как файлы UTF-8.

8
ответ дан 31 October 2019 в 16:07

Регистрируйте/Совершенствуйте Сохраняют Опции/Кодирование: "Unicode (UTF-8 без подписи ) - Кодовая страница 65001"

14
ответ дан 31 October 2019 в 16:07

Брофилд,

я имел ту же самую проблему и просто наткнулся на решение, которое не требует преобразования Ваших исходных строк к широким символам и назад: сохраните свой исходный файл как UTF-8 без , подпись и VC2008 оставят его в покое. Работавший отлично, когда я выяснил для отбрасывания подписи.Подводя итоги:

Unicode (UTF-8 без подписи) - Кодовая страница 65001, не бросает предупреждение c4566 в VC2008 и не заставляет VC смешивать с кодированием, в то время как Кодовая страница 65001 (UTF-8 С Подписью) действительно бросает c4566 (поскольку Вы нашли).

Hope это не слишком поздно для помощи Вам, но это могло бы ускорить Ваше приложение VC2008 для удаления обходного решения.

16
ответ дан 31 October 2019 в 16:07

Как насчет этого? Вы храните строки в закодированном файле UTF-8 и затем предварительно обработайте их в закодированный исходный файл C++ ASCII. Вы сохраняете кодировку UTF-8 в строке при помощи шестнадцатеричных Escape. Строка

"中国語 (繁体)"

преобразовывается в

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

, Конечно, это нечитабельно любым человеком, и цель состоит в том, чтобы только избежать проблем с компилятором.

Вы могли или использовать препроцессор C++ для ссылки на строки в преобразованном заголовочном файле, или Вы могли преобразовать Вас весь источник UTF-8 в ASCII перед компиляцией с помощью этого приема.

4
ответ дан 31 October 2019 в 16:07

Другие вопросы по тегам:

Похожие вопросы: