В чем разница между _tcslen и _tcsclen?

Я разрабатываю приложение, которое должно быть совместимо с различными кодировками кодировок. Для этого я всегда использую TCHAR* вместо char* для определения строк. Поэтому я использую _tcslen, чтобы получить размер моих строк.

Сегодня я увидел в системе управления версиями моей компании, что один из моих коллег по работе отредактировал строку, где я написал _tcslen, чтобы использовать вместо нее _tcsclen.

Единственная найденная мной ссылка, говорящая об особенностях этой функции, — это эта и это не объясняет разницу между этими функциями.

Может кто-нибудь объяснить мне разницу между _tcslen и _tcsclen?


person Pierre    schedule 07.05.2018    source источник
comment
В ссылке, которую вы разместили, yhey сопоставляется с другой функцией в зависимости от #define (s). Если вам нужна поддержка MBCS, я думаю, ваш напарник прав. См. раздел комментариев.   -  person Richard Critten    schedule 07.05.2018
comment
@RichardCritten Я уверен, что он прав. Действительно, нам нужна MBCS, потому что, я думаю, приложение кроссплатформенное и принимает разные кодировки. Но я действительно не понимаю, почему мы должны предпочесть _tcsclen _tcslen. Каковы различия между ними? В каких случаях следует использовать тот или иной?   -  person Pierre    schedule 07.05.2018
comment
Маловероятно, что вам нужно использовать TCHAR. Я думаю, вы не поддерживаете Windows 9x.   -  person David Heffernan    schedule 07.05.2018
comment
Учитывая, что длина, вероятно, используется для памяти, а не для целей рендеринга (кто делает это вручную?), напарник, вероятно, ошибся и внес серьезную ошибку.   -  person Chris Becke    schedule 08.05.2018


Ответы (2)


Префикс _t означает, что это функции обработки текста (на самом деле макросы), которые сопоставляются с различными реализациями, в зависимости от того, компилируете ли вы для «Unicode» (фактически UTF-16) или нет.

Когда вы компилируете для Unicode (установлено _UNICODE), они сопоставляются с одной и той же функцией, wcslen, которая возвращает длину строки в расширенных (двухбайтовых) символах.

Когда вы не компилируете для Unicode (установлено _MBCS), они сопоставляются с разными функциями:

  • _tcslen сопоставляется с strlen, что возвращает длину строки в байтах. Это сделано для того, чтобы вы могли выделить буферы нужного размера.
  • _tcsclen сопоставляется с _mbslen, документация по которому довольно скудна. Однако я предполагаю, что c в _tcsclen означает символы.

Разница между символами и байтами заключается в том, что в многобайтовой кодировке конкретный символ может занимать от одного до трех байтов. Таким образом: _tcsclen (_mbslen) говорит вам, сколько символов в строке, что полезно для рендеринга, а _tcslen (strlen) говорит вам, сколько байтов в строке, что вам нужно для выделения памяти.

В общем, если вы работаете в основном с Windows, вы просто скомпилируете для Unicode и покончите с этим. Вам нужно иметь дело с другими кодировками символов, только если вы разговариваете с другой системой (чтение/запись файлов, сетевых сообщений и т. д.), и вы обычно конвертируете в UTF-8 и обратно.

Обратите внимание, что когда в документации Windows SDK упоминается "многобайтовая", имеется в виду более старая многобайтовая кодировка, например Shift-JIS, а не UTF-8 (которая также является многобайтовой кодировкой). ).

person Roger Lipscombe    schedule 07.05.2018
comment
Юникод (на самом деле UTF-16) не обязательно верен, я думаю. Вы также можете иметь символы Юникода, закодированные, скажем, в UTF-8? - person Vijay Chavda; 25.12.2019
comment
@VijayChavda в Windows компиляция для Unicode означает UTF-16. UTF-8 тогда еще не изобрели. - person Roger Lipscombe; 26.12.2019
comment
c в _tcslen имеет отношение к const. это означает, что он дает вам длину указателя строки const, будь то const char * или const wchar_t *. - person Jonathan; 12.04.2021

Когда установлен флаг компилятора Windows _MBCS, _tcslen сопоставляется с strlen, а _tcsclen сопоставляется с _mbslen. Когда установлен флаг Windows _UNICODE, обе общие функции сопоставляются с wcslen.

person Mandar    schedule 07.05.2018