Spec-Zone.ru › C++

std::codecvt<InternT,ExternT,StateT>::out, do_out

Определено в заголовочном файле <locale>
public:
result out( StateT& state,
            const InternT* from,
            const InternT* from_end,
            const InternT*& from_next,
            ExternT* to,
            ExternT* to_end,
            ExternT*& to_next ) const;
(1)
protected:
virtual result do_out( StateT& state,
                       const InternT* from,
                       const InternT* from_end,
                       const InternT*& from_next,
                       ExternT* to,
                       ExternT* to_end,
                       ExternT*& to_next ) const;
(2)
1) Публичный член-функция, вызывает член-функцию do_out самого производного класса.
2) Если этот codecvt фасет определяет преобразование, переводит внутренние символы из диапазона исходных значений [from, from_end) во внешние символы, помещая результаты в последующие места, начиная с to. Преобразует не более from_end - from внутренних символов и записывает не более to_end - to внешних символов. Оставляет from_next и to_next указывающие на элемент, следующий за последним успешно преобразованным элементом.

Если этот codecvt фасет не определяет преобразование, символы не преобразуются. to_next устанавливается равным to, state остается неизменным, и возвращается std::codecvt_base::noconv.

do_out(state, from, from + 1, from_next, to, to_end, to_next) должен возвращать ok если

  • этот codecvt фасет используется basic_filebuf, и
  • do_out(state, from, from_end, from_next, to, to_end, to_next) вернул бы ok там, где from != from_end.

Возвращаемое значение

Значение типа std::codecvt_base::result, указывающее на статус успеха следующим образом:

ok преобразование завершено
partial недостаточно места в буфере вывода или неожиданный конец буфера входных данных
error обнаружен символ, который не может быть преобразован
noconv этот фасет не выполняет преобразование, вывод не записан

Непреобразующий специализация std::codecvt<char, char, std::mbstate_t> всегда возвращает std::codecvt_base::noconv.

Примечания

Требует, чтобы from <= from_end && to <= to_end и чтобы state либо представляли начальное состояние сдвига, либо были получены путем преобразования предыдущих символов в последовательности.

Хотя codecvt поддерживает преобразования N:M (например, UTF-16 в UTF-8, где для определения внешних символов, подлежащих выводу, могут потребоваться два внутренних символа), std::basic_filebuf может использовать только codecvt фасеты, которые определяют преобразование 1:N, то есть он должен быть в состоянии обрабатывать по одному внутреннему символу за раз при записи в файл.

При выполнении преобразований N:M эта функция может вернуть std::codecvt_base::partial после потребления всех символов источника (from_next == from_end). Это означает, что для завершения преобразования необходим еще один внутренний символ (например, при преобразовании UTF-16 в UTF-8, если последний символ в буфере источника — старший суррогат).

Влияние на state намеренно не определено. В стандартных фасетах он используется для поддержания состояния сдвига, как при вызове std::wcsrtombs, и, следовательно, обновляется для отражения состояния сдвига после последнего успешно преобразованного символа, но пользовательский фасет свободен использовать его для поддержания любого другого состояния, например, подсчета количества встреченных специальных символов.

Пример

#include <iostream>
#include <locale>
#include <string>
 
int main()
{
    std::locale::global(std::locale("en_US.utf8"));
    auto& f = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(std::locale());
    std::wstring internal = L"z\u00df\u6c34\U0001f34c"; // L"zß水🍌"
 
    // note that the following can be done with wstring_convert
    std::mbstate_t mb{}; // initial shift state
    std::string external(internal.size() * f.max_length(), '\0'); 
    const wchar_t* from_next;
    char* to_next;
    f.out(mb, &internal[0], &internal[internal.size()], from_next,
              &external[0], &external[external.size()], to_next);
    // error checking skipped for brevity
    external.resize(to_next - &external[0]);
 
    std::cout << "The string in narrow multibyte encoding: " << external << '\n';
}

Вывод:

The string in narrow multibyte encoding: zß水🍌

Отчеты об ошибках

Следующие отчеты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применен к Поведение, как опубликовано Правильное поведение
LWG 76 C++98 неясно, требуется ли преобразование
для поддержки обработки по одному внутреннему символу за раз
требуется только если используется
в basic_filebuf

См. также

overflow
[virtual]
записывает символы в связанный файл из области записи
(виртуальная защищенная член-функция std::basic_filebuf<CharT,Traits>)
to_bytes
преобразует строку с широкими символами в строку байтов
(публичная член-функция std::wstring_convert<Codecvt,Elem,Wide_alloc,Byte_alloc>)
wcsrtombs
преобразует строку с широкими символами в узкую строку с многобайтовыми символами, задано состояние
(функция)
do_in
[virtual]
преобразует строку из ExternT в InternT, например, при чтении из файла
(виртуальная защищенная член-функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/locale/codecvt/out

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API