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

Есть несколько способов использовать

1) Читать с fread после вставки в одну строку

library(data.table)
fread(paste(sub('"', "", df1$H), collapse="\n"), sep="'")[, 
               as.matrix(.SD) %*% c(30.48, 2.54)][,1]
 #[1] 187.96 177.80 165.10 154.94 165.10 162.56

2) [ 1114] Использование gsubfn

library(gsubfn)
as.numeric(gsubfn("(\\d)'(\\d+)", ~ as.numeric(x) * 30.48 + 
            as.numeric(y) * 2.54, sub('"', '', df1$H)))
 #[1] 187.96 177.80 165.10 154.94 165.10 162.56

3) с separate

library(tidyverse)
df1 %>% 
    separate(H, into = c("H1", "H2"), convert = TRUE) %>%
    transmute(H = H1 * 30.48 + H2 * 2.54)
# A tibble: 6 x 1
#      H
#  <dbl>
#1  188.
#2  178.
#3  165.
#4  155.
#5  165.
#6  163.

4) с measurements [1112 ]

library(measurements)
library(tidyverse)
df1 %>% 
   separate(H, into = c("H1", "H2"), convert = TRUE) %>%
   transmute(H = conv_unit(H1, "ft", "cm") + conv_unit(H2, "inch", "cm"))
62
задан brofield 29 March 2009 в 03:29
поделиться

10 ответов

Обновление:

Я решил, что нет никакого гарантируемого способа сделать это. Решение, которое я представляю ниже работ для английской версии 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
ответ дан brofield 24 November 2019 в 16:50
поделиться

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

-6
ответ дан 24 November 2019 в 16:50
поделиться

У меня была подобная проблема, решение состояло в том, чтобы сохранить в усовершенствованном использовании бума UTF8 withou, сохраняют опции

0
ответ дан 24 November 2019 в 16:50
поделиться

В то время как, вероятно, лучше использовать широкие строки и затем преобразовать по мере необходимости в UTF-8. Я думаю, что Ваш лучший выбор к тому, поскольку Вы упомянули шестнадцатеричные Escape использования в строках. Как предполагают, что Вы хотели кодовую точку \uC911, Вы могли просто сделать это.

const char *str = "\xEC\xA4\x91";

Я полагаю, что это будет работать просто великолепно, просто не очень читаемо, поэтому если Вы делаете это, прокомментируйте это для объяснения.

15
ответ дан Evan Teran 24 November 2019 в 16:50
поделиться

Как насчет этого? Вы сохраняете строки в файле с кодировкой 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
ответ дан 24 November 2019 в 16:50
поделиться

Может быть, попробовать поэкспериментировать:

#pragma setlocale(".UTF-8")

или:

#pragma setlocale("english_england.UTF-8")
1
ответ дан 24 November 2019 в 16:50
поделиться

По умолчанию Visual Studio помещает слово «использование» в верхней части файлов. Однако рекомендуемый подход заключается в помещении операторов using внутри пространства имен. Даже stylecop от MS улавливает это и говорит, что использование VS по умолчанию неверно.

Оба метода работают нормально.

Правило StyleCop гласит: Размещение нескольких элементов пространства имен в одном файле обычно плохая идея, но если и когда это готово, рекомендуется разместить все using директивы в каждом из элементы пространства имен, а не глобально вверху файла. Эта будет ограничивать пространства имен плотно, и также поможет избежать поведение, описанное выше.

Важно отметить, что когда код был написан с использованием директив размещен вне пространства имен, забота следует принимать во внимание при перемещении этих директивы в пространстве имен, чтобы убедитесь, что это не меняет семантика кода. Как объяснено выше, разместив директивы using-alias внутри элемента пространства имен позволяет компилятор на выбор конфликтующие типы, которые будут не происходит, когда директивы размещены за пределами пространства имен.

Вот некоторые ссылки для дальнейшего изучения:

-38 -

Брофилд,

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

16
ответ дан 24 November 2019 в 16:50
поделиться

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

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

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

Может быть, это поможет ...

1
ответ дан 24 November 2019 в 16:50
поделиться

Файл / Расширенные параметры сохранения / Кодировка: «Юникод (UTF-8 без подписи ) - Кодовая страница 65001 "

14
ответ дан 24 November 2019 в 16:50
поделиться
Другие вопросы по тегам:

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