Как вы определяете длину неподписанного символа *? - PullRequest
20 голосов
/ 07 мая 2009

Как вы определяете длину неподписанного символа *?

Ответы [ 6 ]

29 голосов
/ 07 мая 2009

Для фактического размера указателя:

size_t s = sizeof(unsigned char*);

Если вы хотите длину строки:

unsigned char* bla = (unsigned char*)"blabla";
int s = strlen((char*)bla);
9 голосов
/ 07 мая 2009

Это может иметь два значения. Вы просто хотите узнать, насколько велик тип указателя? Если так, то ответ Джоуса верен

size_t size = sizeof(unsigned char*);

Если вы хотите узнать, на сколько элементов указывает указатель, это немного сложнее. Если это строка в стиле C, тогда strlen или другой вариант - ваш лучший вариант.

Однако, если это просто указатель на unsigned char, который не имеет отношения к строке стиля C, то нет способа надежно достичь того, что вы ищете. C / C ++ не связывает поле длины с указателем. Вам нужно будет передать длину с помощью указателя или использовать класс-вектор, который хранит как указатель, так и длину.

8 голосов
/ 08 мая 2009

В идеальном мире это не так. Вы используете char * для строк в стиле C (которые заканчиваются NUL и вы можете измерить длину), а unsigned char * только для байтовых данных (длина которых указывается в другом параметре или в любом другом месте, и в которые вы, вероятно, попадете контейнер STL КАК МОЖНО СКОРЕЕ, например vector<unsigned char> или basic_string<unsigned char>).

Основная проблема заключается в том, что вы не можете делать переносимые предположения о том, совпадают ли представления памяти для char и unsigned char. Обычно они есть, но им позволено не быть. Таким образом, нет строковых библиотечных функций, которые работают с unsigned char *, только с char *, и в общем случае небезопасно приводить unsigned char * к знаку char * и обрабатывать результат как строку. Поскольку char может быть подписан, это означает, что нет приведения неподписанного char * к char *.

Однако, 0 всегда одно и то же представление значения в беззнаковых символах и символах. Так что в неидеальном мире, если у вас есть строка в стиле C откуда-то, но она пришла как беззнаковый char *, то вы (a) приводите ее к char * и продолжаете с ней, но также и (b) ) узнай, кто сделал это с тобой, и попроси их прекратить.

0 голосов
/ 07 мая 2009

Если вы используете C ++ и его строку в неподписанном символе *, лучше сначала поместить его в std :: string, а затем манипулировать им. Таким образом, вы можете делать с ним все что угодно и при этом иметь возможность получать его длину () и / или емкость () в любое время.

Я предполагаю, что вы делаете что-то с указанным массивом, чтобы сделать его размер непостоянным. Если вы просто размещаете, устанавливаете и забываете, вы всегда можете сохранить фактический размер размещения массива в отдельной переменной - или, лучше, создать структуру / класс.

//WARNING: memory issues not addressed here.
struct myStringStruct
{
  unsigned char * string;
  int len;

  allocate(int size) {
    len = size;
    string = malloc(sizeof(unsigned char) * len);
  }
}

Более сложный вариант, и вы заново изобретаете std :: string.

0 голосов
/ 07 мая 2009

Вы хотите, чтобы длина указателя была бы int. Если вы хотите длину строки, на которую указывает, используйте strlen: например Размер указателя: sizeof (беззнаковый символ *) Размер строки: strlen (без знака char *) Многобайтовые символы будут сообщаться как ..multi byte

0 голосов
/ 07 мая 2009

Под знаком без знака * Я полагаю, вы имеете в виду строку, расположенную по этому указателю. В этом случае это будет:

strlen(your_string_pointer)

Однако, это только найдет позицию \ 0. Нет гарантии, что это фактический размер выделенного блока памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...