Как определить размер строки в C или, по крайней мере, убедиться, что он не превышает максимальное количество байтов?

#c

#c

Вопрос:

Возможно ли определить размер строки в байтах в C?

Я пытаюсь убедиться, что строки JSON, встроенные в C, не превышают ограничение в размере 1 МБ, прежде чем передавать их запрашивающему приложению. Я не знаю строки во время компиляции.

Я читал, что это просто strlen * sizeof( char ) ; но я этого не понимаю, потому что я читал в другом месте, что UTF-8 может содержать символы размером до четырех байт и sizeof( char ) всегда равен единице.

Я, вероятно, неправильно понимаю что-то основное.

Если массив символов выделяется как char JSON[1048576] , выделяет ли это столько символов или байтов? Если это байты, то до тех пор, пока snprintf при записи в массив JSON используется что-то подобное, гарантирует ли это, что его размер никогда не может превышать 1 МБ, даже если в этом массиве были символы, превышающие один байт?

Спасибо.

Комментарии:

1. Один char гарантирует, что его размер равен 1 байту.

2. @Rohan Bari Спасибо. Я наткнулся на сайт, который утверждает, что вычисляет размер байта любой строки в C и показывает пример i ♥ u и говорит, что это 7 байт. Если сердце равно 3 байтам, как char гарантировать, что оно будет одним байтом или займет 3 символа?

3. Да, он занимает до 3 символов. Смотрите демонстрацию.

4. @RohanBari Спасибо. Я не думал, что это так просто. Я заглянул в <string.h> заголовок и, поскольку использую MinGW-W64, в нем есть только одна строка, которая использует strlen функцию Windows, и они заявляют, что «strlen интерпретирует строку как однобайтовую символьную строку, поэтому ее возвращаемое значение всегда равно количеству байтов, даже если строка содержит многобайтовые символы.» Это то, чего я не понимал.

Ответ №1:

Поскольку вам нужно ограничение размера 1MB , а не ограничение длины строки как таковое, вы можете просто использовать strlen(json_str) . При условии, что ваша строка json завершается нулем, '' .

Если вы выделите char JSON[1048576] это, вы получите массив с таким количеством байтов. И snprintf(JSON, 1048576, "<json string>", ...) гарантирует, что вы никогда не переполните свой массив.

Однако это не гарантирует, что ваша строка является допустимой строкой utf-8, поскольку последний символ может быть многобайтовым символом, который разделяется посередине.

C — char это не то же самое, что символ utf-8. В C char по определению 1 байт, но в utf-8 визуальный символ, который вы хотите, например, сердечко в вашем комментарии, может быть представлен несколькими байтами данных. Один байт дает вам 256 различных значений, а поскольку для кодирования многих из них требуется более 256 символов Юникода, требуется более одного байта. Разработчики utf-8 были умны, поэтому первые 127 символов могут быть закодированы с использованием всего одного байта, и если используются только эти символы, будут действительны как utf-8, так и ascii.

Комментарии:

1. Спасибо за объяснение. Эта часть о разрыве на части многобайтового символа — ошибка. Вы случайно не знаете, как это следует обрабатывать? Если strlen размер JSON превышает 1 МБ, я экранировал все двойные кавычки и передавал их по частям как обычную строку и объединял их в запрашивающем приложении. перед попыткой синтаксического анализа как JSON. Даже если разрыв был на однобайтовом символе, в моем случае это был бы недопустимый JSON, поскольку это только часть полной строки JSON. Я предполагаю, что в многобайтовом сценарии после конкатенации он все равно будет успешно проанализирован?

2. Забавно, тоже, в некотором смысле, потому что у меня все было наоборот, думая, что strlen это длина в символах независимо от размера байта. Вместо strlen этого возвращает байты, и никто не знает, сколько символов в этих байтах.

3. Если JSON может содержать UTF-8, то вам все равно не следует использовать strlen . Вам придется использовать многобайтовые строки, функции с расширенными символами, преобразования и т. Д. Я бы сказал, что обработка UTF-8, вероятно, является продвинутой темой.