iconv всегда EILSEQ

240
29 июня 2018, 02:30
std::string decode_to_ascii(char* input, const size_t& input_len)
{
    iconv_t cb = iconv_open("ASCII//IGNORE", "UTF-8");
    if (cb == (iconv_t)(-1))
    {
        return "";
    }
    char* out = new char[input_len];
    size_t in_l = input_len;
    size_t out_l = input_len;
    size_t cvtlen = iconv(cb, &input, &in_l, &out, &out_l);
    if (cvtlen == (size_t)(-1))
    {
        auto err = errno;
        return "";
    }
    std::string result(out);
    iconv_close(cb);
    return result;
}

iconv всегда выдает ошибку EILSEQ с указанием на последний символ, что не так?

входной буфер гарантированно имеет кодировку УТФ-8, строка корректно кодируется другими средствами и корректно отображается в текстовом редакторе, если её сохранить в файл.

//IGNORE или //TRANSLIT не дают эффекта, пробовал совать туда 1 двухбайтовый символ, эффекта нет

Замечено, что на одних и тех же входных данных iconv выдает различный результат...

Answer 1

Ошибка EILSEQ означает невалидные символы во входном буфере, однако при использовании с "ASCII//IGNORE" эта ошибка будет возвращаться в случае, если некоторые символы были отброшены. При этом указатель на входную строку будет указывать на проблемный байт - сразу за пределом входной строки. Таким образом, можно разделить ситуации, когда невалидная последовательность реально была во входной строке, и когда какие-то символы были отброшены. Также не следует передавать оригинальный указатель на выходной буфер (после вызовы функции он будет указывать на байт сразу после записанных) и не следует передавать оригинальный указатель на выходной буфер в функции, ожидающие заканчивающуюся нулем строку:

char * p_in{input};
size_t out_l{input_len};
char * p_out{out};
size_t out_l{input_len};
errno = 0;
size_t const cvtlen{iconv(cb, &p_in, &in_l, &p_out, &out_l)};
if (cvtlen == (size_t)(-1))
{
    auto const err{errno};
    if((EILSEQ != errno) || (p_in != (input + input_len)))
    {
        return "";
    } 
}
std::string result(out, static_cast<::std::size_t>(p_out - out));
READ ALSO
Определение геолокации. Клиентский JS

Определение геолокации. Клиентский JS

Как определить геолокацию пользователя? Как я понял это делается через

211
График из 1000000 точек

График из 1000000 точек

Необходимо построить line график на странице, который содержит в себе примерно миллион (+- 1000) точекЛучший вариант - изображать только часть...

380
Хранение массива в памяти

Хранение массива в памяти

Как хранится массив в памяти? В си это непрерывная область памяти с доступом к любому элементу за константуТакое ли представление массива...

248