Компиляторы C реализуют один из нескольких стандартов. Однако наличие стандарта не означает, что все аспекты языка определяются. устройство Вареного пудинга , например, является фаворитом 'скрытая' функция, которая стала столь популярной, что современные компиляторы имеют код распознавания особого назначения, чтобы гарантировать, чтобы методы оптимизации не ударяли желаемый эффект этого часто используемый шаблон.
В общих скрытых функциях или приемах языка препятствуются, поскольку Вы работаете на краю бритвы того, какой бы ни стандарт (стандарты) C Ваш компилятор использует. Много таких приемов не работают от одного компилятора до другого, и часто эти виды функций перестанут работать от одной версии пакета компилятора данным производителем к другой версии.
Различные приемы, которые повредили код C, включают:
Другие проблемы и проблемы, которые возникают каждый раз, когда программисты делают предположения о моделях выполнения, которые все определяются в большинстве стандартов C как 'зависимое поведение' компилятора.
Вот два возможных решения - 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;
}
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.
Есть ли причина, по которой вам нужно объявлять столбец базы данных в байтах? Это значение по умолчанию, но оно не особенно полезно по умолчанию, если набор символов базы данных имеет переменную ширину. Я бы очень предпочел объявить столбец в виде символов.
CREATE TABLE length_example (
col1 VARCHAR2( 10 BYTE ),
col2 VARCHAR2( 10 CHAR )
);
Это создаст таблицу, в которой COL1 будет хранить 10 байтов данных, а col2 - 10 символов данных. Семантика длины символа имеет гораздо больший смысл в базе данных UTF8.
Предполагая, что вы хотите, чтобы все создаваемые вами таблицы использовали семантику длины символов по умолчанию, вы можете установить для параметра инициализации NLS_LENGTH_SEMANTICS
значение CHAR. На этом этапе любые таблицы, которые вы создаете, по умолчанию будут использовать семантику длины символа, а не семантику длины байта, если вы не укажете CHAR или BYTE в длине поля.