Лучший способ укоротить строку UTF8 на основе длины байта

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

В общих скрытых функциях или приемах языка препятствуются, поскольку Вы работаете на краю бритвы того, какой бы ни стандарт (стандарты) C Ваш компилятор использует. Много таких приемов не работают от одного компилятора до другого, и часто эти виды функций перестанут работать от одной версии пакета компилятора данным производителем к другой версии.

Различные приемы, которые повредили код C, включают:

  1. Доверие, как компилятор размечает структуры в памяти.
  2. Предположения на порядок байтов из целых чисел/плаваний.
  3. Предположения на функциональном ABIs.
  4. Предположения на направлении, что стековые фреймы растут.
  5. Предположения о порядке выполнения в операторах.
  6. Предположения о порядке выполнения операторов в аргументах функции.
  7. Предположения на диаметре долота или точности коротких, международных, длинных, и двойных типов плавающих.

Другие проблемы и проблемы, которые возникают каждый раз, когда программисты делают предположения о моделях выполнения, которые все определяются в большинстве стандартов C как 'зависимое поведение' компилятора.

14
задан OMG Ponies 1 April 2011 в 16:56
поделиться

3 ответа

Вот два возможных решения - LINQ однострочная обработка ввода слева направо и традиционная для -цикла, обрабатывающая ввод справа налево. Какое направление обработки будет быстрее, зависит от длины строки, допустимой длины в байтах, а также количества и распределения многобайтовых символов, и трудно дать общее предложение. Выбор между LINQ и традиционным кодом у меня, вероятно, дело вкуса (или, может быть, скорости).

Если скорость имеет значение, можно подумать о том, чтобы просто накапливать байтовую длину каждого символа до достижения максимальной длины вместо вычисления байтовой длины вся строка на каждой итерации. Но я не уверен, что это сработает, потому что я не Я достаточно хорошо знаю кодировку UTF-8. Теоретически я мог бы представить, что длина строки в байтах не равна сумме длин байтов всех символов.

public static String LimitByteLength(String input, Int32 maxLength)
{
    return new String(input
        .TakeWhile((c, i) =>
            Encoding.UTF8.GetByteCount(input.Substring(0, i + 1)) <= maxLength)
        .ToArray());
}

public static String LimitByteLength2(String input, Int32 maxLength)
{
    for (Int32 i = input.Length - 1; i >= 0; i--)
    {
        if (Encoding.UTF8.GetByteCount(input.Substring(0, i + 1)) <= maxLength)
        {
            return input.Substring(0, i + 1);
        }
    }

    return String.Empty;
}
13
ответ дан 1 December 2019 в 07:27
поделиться

If a UTF-8 byte has a zero-valued high order bit, it's the beginning of a character. If its high order bit is 1, it's in the 'middle' of a character. The ability to detect the beginning of a character was an explicit design goal of UTF-8.

Check out the Description section of the wikipedia article for more detail.

4
ответ дан 1 December 2019 в 07:27
поделиться

Есть ли причина, по которой вам нужно объявлять столбец базы данных в байтах? Это значение по умолчанию, но оно не особенно полезно по умолчанию, если набор символов базы данных имеет переменную ширину. Я бы очень предпочел объявить столбец в виде символов.

CREATE TABLE length_example (
  col1 VARCHAR2( 10 BYTE ),
  col2 VARCHAR2( 10 CHAR )
);

Это создаст таблицу, в которой COL1 будет хранить 10 байтов данных, а col2 - 10 символов данных. Семантика длины символа имеет гораздо больший смысл в базе данных UTF8.

Предполагая, что вы хотите, чтобы все создаваемые вами таблицы использовали семантику длины символов по умолчанию, вы можете установить для параметра инициализации NLS_LENGTH_SEMANTICS значение CHAR. На этом этапе любые таблицы, которые вы создаете, по умолчанию будут использовать семантику длины символа, а не семантику длины байта, если вы не укажете CHAR или BYTE в длине поля.

2
ответ дан 1 December 2019 в 07:27
поделиться
Другие вопросы по тегам:

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