Необработанные строковые литералы и кодификация файлов

C ++ 11 представил необработанные строковые литералы что может быть очень полезно для представления строк в кавычках, литералов с множеством специальных символов, таких как пути к файлам Windows, выражения регулярных выражений и т. д.

std::string path = R"(C:\teamwork\new_project\project1)"; // no tab nor newline!
std::string quoted = R"("quoted string")";
std::string expression = R"([\w]+[ ]+)";

Эти необработанные строковые литералы также можно комбинировать с префиксами кодирования (u8, u, U, или же L), но если префикс кодирования не указан, имеет ли значение кодировка файла?, давайте предположим, что у меня есть этот код:

auto message = R"(Pick up a card)";         // raw string 1
auto cards = R"(����������������������������)"; // raw string 2

Если я смогу написать и сохранить приведенный выше код, очевидно, что мой исходный код закодирован как Unicode, поэтому мне интересно:

  • raw string 1 будет ли Unicode буквальным? (хотя он использует только символы ASCII), другими словами, наследует ли необработанная строка кодификацию файла, в котором написано, или компилятор автоматически определяет, что unicode не нужен, независимо от кодировки файла?
  • Нужен был бы префикс кодировки U на raw string 2 для того, чтобы рассматривать его как литерал Юникода, или он будет автоматически в Юникоде из-за его содержимого и / или кодировки исходного файла?

Спасибо за внимание.

РЕДАКТИРОВАТЬ:

Тестирование приведенного выше кода на ideone.com и распечатка message а также cards переменные, это выводит char const*:

template<typename T> std::string demangle(T t)
{
int status;
char *const name = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
std::string result(name);
free(name);
return result;
}

int main()
{
auto message = R"(Pick up a card)";
auto cards = R"(����������������������������)";

std::cout
<< "message type: " << demangle(message) << '\n'
<< "cards type: " << demangle(cards) << '\n';

return 0;
}

Выход:

message type: char const*

cards type: char const*

что даже более странно, чем я думал, я был уверен, что тип будет wchar_t (даже без L префикс).

3

Решение

Да, это важно, даже для компиляции вашего источника. Вам нужно будет использовать somenthing, как -finput-charset=UTF-16 компилировать, если вы используете gcc (то же самое должно относиться к VS).

Но я, IHMO, есть кое-что более фундаментальное, чтобы принять во внимание в вашем коде. Например, std::string контейнеры для char, что составляет 1 байт. Если вы имеете дело, например, с UTF-16, вам потребуется 2 байта, поэтому (несмотря на «ручное преобразование») вам понадобится как минимум wchar_t (std :: wstring) (или, чтобы быть более безопасным, char16_t, чтобы быть в безопасности C++11).

Таким образом, для использования Unicode вам понадобится контейнер для него и среда компиляции, подготовленная для обработки ваших кодифицированных источников Unicode.

1

Другие решения

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

Тип строкового литерала и соответствующая кодировка выполнения полностью определяются префиксом. R один всегда производит char Строка в узком исполнении кодировки. Если источником является UTF-16 (а компилятор поддерживает UTF-16 в качестве кодировки источника), то компилятор преобразует содержимое строкового литерала из UTF-16 в кодировку с узким исполнением.

1

По вопросам рекламы [email protected]